This is an R Notebook which describes the distant reading process used for my project. There are brief descriptors above each code chunk which describe what was done, with more detailed commentary in the coding sections which are noted with a “#” sign. Downloading the whole folder “Neural Network Usage in Science” and opening in Studio R will let you run this code on your own.
Once the database was downloaded, according to the specification in the methodology section, I load all the databases from different years. I dropped the columns that weren’t of interest and renamed those that were for easier use. Just incase of duplicates, I extracted the unique instances of rows. I discarded duplicate rows and columns that contained no information at all. I created a unique ID per article to make identifying specific articles easier to find if necessary. When data wasn’t available, Scopus used a text of “[x category is not available]” instead of just “NA”. To convert to NA sections, I filtered for rows that contained “available]” and copied the message precisely. That way I equated the message to an “NA” text for easier usage.
#loading the necesary packages for this code
library(dplyr)
library(tidyr)
library(ggplot2)
library(readr)
library(stringr)
library(skimr)
library(splitstackshape)
library(janitor)
library(jcolors)
library(wordcloud)
library(wordcloud2)
library(tm)
library(data.table)
#loading the csv files and then joining them in to one data base
##converting blanks in to NA
#2010 data bases
data.10.o <- read.csv ("2010_no_articles.csv", na.strings = c("", "NA"))
data.10.a <- read.csv ("2010_yes_articles.csv", na.strings = c("", "NA"))
#2011 data bases
data.11.o <- read.csv ("2011_no_articles.csv", na.strings = c("", "NA"))
data.11.a <- read.csv ("2011_yes_articles.csv", na.strings = c("", "NA"))
#2012 databases
data.12.o <- read.csv ("2012_no_articles.csv", na.strings = c("", "NA"))
data.12.a <- read.csv ("2012_yes_articles.csv", na.strings = c("", "NA"))
#2013 databases
data.13.o <- read.csv ("2013_no_articles.csv", na.strings = c("", "NA"))
data.13.a <- read.csv ("2013_articles.csv", na.strings = c("", "NA"))
#2014 databases
data.14.a <- read.csv ("2014_articles.csv", na.strings = c("", "NA"))
data.14.o <- read.csv ("2014_other.csv", na.strings = c("", "NA"))
#2015 databases
data.15.a <- read.csv ("2015_articles.csv", na.strings = c("", "NA"))
data.15.o <- read.csv ("2015_other.csv", na.strings = c("", "NA"))
#2016 database
## everything fit in one for 2016
data.16.all <- read.csv ("2016_all.csv", na.strings = c("", "NA"))
#2017 database
## everything fir in one for 2017
data.17.all <- read.csv ("2017_all.csv", na.strings = c("", "NA"))
#2018 database
data.18.a <- read.csv ("2018_articles.csv", na.strings = c("", "NA"))
data.18.o <- read.csv ("2018_other.csv", na.strings = c("", "NA"))
#2019 database
data.19.a <- read.csv ("2019_articles.csv", na.strings = c("", "NA"))
data.19.n <- read.csv ("2019_notes.csv", na.strings = c("", "NA"))
data.19.o <- read.csv ("2019_other.csv", na.strings = c("", "NA"))
#2020 database
data.20.n <- read.csv ("2020_notes.csv", na.strings = c("", "NA"))
data.20.o <- read.csv ("2020_other_articles.csv", na.strings = c("", "NA"))
#putting the databases together into one
data.original <- rbind(data.10.a, data.10.o,
data.11.a, data.11.o,
data.12.a, data.12.o,
data.13.a, data.13.a,
data.14.a, data.14.o,
data.15.a, data.15.o,
data.16.all,
data.17.all,
data.18.o, data.18.a,
data.19.a, data.19.n, data.19.o,
data.20.n, data.20.o)
#cleaning the csv file
## discarding some of the columns that won't be used
## renaming the column titles so they're not capitalized
## converting lack of information notes in to NA strings
## adding an id to each column
data.original <- data.original %>%
select(-Art..No., -Molecular.Sequence.Numbers, -Chemicals.CAS,-Tradenames, -Manufacturers, -Funding.Text.1, -Funding.Text.2, -Funding.Text.3, -Funding.Text.4, -Funding.Text.5, -Funding.Text.6, -Funding.Text.7, -Funding.Text.8, -Funding.Text.9, -Funding.Text.10, -Correspondence.Address, -Abbreviated.Source.Title)
#renaming the columns for easier handling
names(data.original) <- c("authors", "author.id", "title", "year", "source.title", "volume", "issue", "page.start", "page.end", "page.count", "cited.by", "doi", "link", "affiliations", "author.affiliations", "abstract", "author.keywords", "index.keywords", "funding.details", "references", "editors", "sponsors", "publisher", "conference.name", "conference.date", "conference.location", "conference.code", "issn", "isbn", "coden", "pubmed.id", "original.language", "document.type", "publication.stage", "open.access", "source", "eid")
#extracting the unique instances
data.original <- unique(data.original)
#checking how many NAs exist within each column
colSums(is.na(data.original))
authors author.id title year source.title
0 1 0 0 0
volume issue page.start page.end page.count
23 17 1563 9201 23889
cited.by doi link affiliations author.affiliations
6234 252 0 7585 567
abstract author.keywords index.keywords funding.details references
0 23887 1127 16182 9190
editors sponsors publisher conference.name conference.date
23889 23889 3149 23889 23889
conference.location conference.code issn isbn coden
23889 23889 3 23888 3
pubmed.id original.language document.type publication.stage open.access
9079 2 1 0 15072
source eid
0 0
##UPDATE HERE WHAT THE NUMBERS ARE BEFORE I RUN THEM
##RETRACT COLUMNS THAT ARE TOTALLY EMPTY
#all columns (except isbn) are totally empty columns
#isbn has one 1 row with data
data.original <- data.original %>%
select(-editors, -sponsors, -conference.name, -conference.date, -conference.location, -conference.code)
#adding a unique id code for all of the columns
data <- data.original %>%
mutate(id = row_number())
#checking which columns use "[No x available]" format
##to be able to copy that format and replace with NA instead
data %>% filter(grepl("available]", authors))
#[No author name available]
data %>% filter(grepl("available]", author.id))
#[No author id available]
#none of these have inserted categories
data %>% filter(grepl("available]", title))
data %>% filter(grepl("available]", year))
data %>% filter(grepl("available]", source.title))
data %>% filter(grepl("available]", volume))
data %>% filter(grepl("available]", issue))
data %>% filter(grepl("available]", page.start))
data %>% filter(grepl("available]", page.end))
data %>% filter(grepl("available]", page.count))
data %>% filter(grepl("available]", cited.by))
data %>% filter(grepl("available]", doi))
data %>% filter(grepl("available]", link))
data %>% filter(grepl("available]", affiliations))
data %>% filter(grepl("available]", author.affiliations))
data %>% filter(grepl("available]", abstract))
#[No abstract available]
data %>% filter(grepl("available]", author.keywords))
data %>% filter(grepl("available]", index.keywords))
data %>% filter(grepl("available]", funding.details))
data %>% filter(grepl("available]", references))
data %>% filter(grepl("available]", publisher))
data %>% filter(grepl("available]", issn))
data %>% filter(grepl("available]", isbn))
data %>% filter(grepl("available]", coden))
data %>% filter(grepl("available]", pubmed.id))
data %>% filter(grepl("available]", original.language))
data %>% filter(grepl("available]", document.type))
data %>% filter(grepl("available]", publication.stage))
data %>% filter(grepl("available]", open.access))
data %>% filter(grepl("available]", source))
data %>% filter(grepl("available]", eid))
#replacing text about missing data for NA instead in the columns that use text to indicate missing information
data <- data %>%
mutate(authors = na_if(authors, "[No author name available]")) %>%
mutate(author.id = na_if(author.id, "[No author id available]")) %>%
mutate(abstract = na_if(abstract, "[No abstract available]"))
To obtain the visualizations about the information of all items in Science from 2010-2020, I calculated the following information: number of issues by year, how many items per volume, and number of items by issue.
#calculating the number of items by issue
number.volumes <- data %>%
count(year)
#renaming
names(number.volumes) <- c("year", "n.items.by.year")
#calculating the number of items by issue
number.issues <- data %>%
group_by(year) %>%
count(issue)
#renaming
names(number.issues) <- c("year", "issue", "n.items.by.issue")
#exporting csv file for write up
write.csv(number.issues, "Items_by_issue.csv")
#calculating the number of issue by year
number.issues.by.year <- data %>%
group_by(year) %>%
count(issue) %>%
select(year, issue) %>%
count(year)
write.csv(number.issues.by.year, "Items_by_year.csv")
#renaming the column to be representative of content, number of items
names(number.issues.by.year) <- c("year", "n.of.issues")
The first graph represents the distribution of items published in science by year.
#graph of the NUMBER OF issues BY YEAR of all science articles 2010-2020
issues.by.year.bar <- ggplot(number.volumes)+
geom_line(aes(x= year, y = n.items.by.year), color = "#5F8495") +
scale_x_continuous(breaks = c(2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020)) +
xlab("Year") +
ylab("Number of items") +
labs(title = "Fig 3. Distribution of amount of items published in science by year, 2010-2020") +
theme_classic()
issues.by.year.bar

The second figure is a histogram of how many citations articles in Science received from 2010-2020, with a bin width of 30 units.
#visualizing distribution of the citation counts for ALL articles in science
#descriptive visualization
## one: histogram of the citation, bins with 30 counts
citation.hist.all <- ggplot(data, aes(x=cited.by)) +
geom_histogram(fill = "#5F8495", binwidth= 30, center = 0.1) +
xlab("Number of citations items recieved") +
ylab("Number of items") +
labs(title = "Fig 1. Distribution of number of citations recieved by items
published in Science, 2010-2020") +
theme(plot.title = element_text(size = 11))
citation.hist.all + theme_classic()

Next, I calculated which issue starts each year. That way later I can add year categories to the figure about amount of items published by issue.
#calculating the first issue number of each year to add labels to the later graph
number.issues %>%
group_by(year) %>%
slice_head(n = 1)
Using the information gathered above I made a graph of number of items published by issue, noting where each year starts.
#tracking the number of articles about neural networks through the issues in science
issues.by.year.bar <- ggplot(number.issues) +
geom_line(aes(x= issue, y = n.items.by.issue), color = "#5F8495") +
scale_x_continuous(breaks = c(5900, 6000, 6100, 6200, 6300, 6400, 6500, 6600, 6700, 6800, 6900)) +
scale_y_continuous(breaks = c(0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150)) +
xlab("Issue number") +
ylab("Number of items by issue") +
labs(title = "Fig 2. Distribution of number of items published in Science by issue, 2010-2020")
issues.by.year.bar + theme_classic() +
#2010
ggplot2::annotate("segment", x = 5961, xend = 5961, y = 0, yend = 150, linetype = 2, colour = "#5F8495") +
ggplot2::annotate("text", x = 5961, y = 160, label = "2010", colour = "#5F8495") +
#2011
ggplot2::annotate("segment", x = 6013, xend = 6013, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6013, y = 160, label = "2011", color = "#99A799") +
#2012
ggplot2::annotate("segment", x = 6064, xend = 6064, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6064, y = 160, label = "2012", color = "#99A799") +
#2013
ggplot2::annotate("segment", x = 6115, xend = 6115, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6115, y = 160, label = "2013", color = "#99A799") +
#2014
ggplot2::annotate("segment", x = 6166, xend = 6166, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6166, y = 160, label = "2014", color = "#99A799") +
#2015
ggplot2::annotate("segment", x = 6217, xend = 6217, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6217, y = 160, label = "2015", color = "#99A799") +
#2016
ggplot2::annotate("segment", x = 6268, xend = 6268, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6268, y = 160, label = "2016", color = "#99A799") +
#2017
ggplot2::annotate("segment", x = 6320, xend = 6320, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6320, y = 160, label = "2017", color = "#99A799") +
#2018
ggplot2::annotate("segment", x = 6371, xend = 6371, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6371, y = 160, label = "2018", color = "#99A799") +
#2019
ggplot2::annotate("segment", x = 6422, xend = 6422, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6422, y = 160, label = "2019", color = "#99A799") +
#2020
ggplot2::annotate("segment", x = 6473, xend = 6473, y = 0, yend = 150, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6473, y = 160, label = "2020", color = "#99A799")

NA
NA
The next figure is a pie chart of all items published, separated by having abstracts or not having abstracts.
#checking how many articles are missing abstracts
#total articles missing abstracts = 13210
data.no.abstract <- data %>%
filter(is.na(abstract)) %>% #filtering those rows in abstract that have NA
mutate(has.abstract = "No")
data.yes.abstract <- data %>%
filter(!(id %in% data.no.abstract$id)) %>% #filtering out those articles already categorized as NA
mutate(has.abstract = "Yes")
data.abstract.both <- rbind(data.no.abstract, data.yes.abstract)
data.abstracts <- data.abstract.both %>%
group_by(has.abstract) %>%
count(has.abstract) %>%
ungroup() %>%
mutate(per = (100*n)/sum(n))
data.abstracts$per <- round(data.abstracts$per)
ggplot(data.abstracts, aes(x="", y = n, fill = has.abstract)) +
geom_col() +
theme_void() +
theme(axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank(),
panel.grid = element_blank()) +
coord_polar("y", start = 0) +
scale_fill_brewer(palette = "pal5") +
geom_text(aes(label = paste0(per,"%")), position = position_stack(vjust=0.5)) +
ggtitle("Fig 4. Percentage of documents with and without abstract information from Science 2010-2020") +
theme(plot.title = element_text(size = 10)) +
guides(fill = guide_legend(title = "Has Abstract"))
Unknown palette pal5

This is a distribution of items published in Science by type, stacked by whether they have abstracts or not.
#stacked bar chart about whether different kinds of documents have abstracts or not
all.abstract.types <- ggplot(data.abstract.both, aes(x = document.type, fill = has.abstract)) +
geom_bar() +
xlab("Kinds of documents") +
ylab("Amount with or without abstract information") +
theme_classic() +
scale_fill_brewer(palette = "pal5") +
ggtitle(" Fig 5. Distribution of Science document types and wether they have abstracts") +
theme(plot.title = element_text(size = 12)) +
guides(fill = guide_legend(title = "Has Abstract"))
Unknown palette pal5
#tilting the text so it is readable and moving downwards
all.abstract.types + theme(axis.text.x = element_text(angle = 45, hjust = 1))

To find articles that I deemed to be related to “artificial neural networks” I researched the following keywords (making sure to disregard lower and upper case differences): Neural network, neural networks, artificial neural network, and artificial neural networks. These were chosen because “neural networks” is the MeSH descriptor (medical subject headings from the national library of medicine) and they are usually a standard for setting database keywords. “Artificial neural networks” is the category that seemed to pop up the most in the journal Science itself, the term that as a journal they seem to have agreed on, so I used that as well. I searched those keywords over the following categories: title, abstract, author keywords and index keywords and extracted the articles that did contain that information. I collected 72 articles in total. Also, I separated out columns so that each column had a distinct piece of information over the following categories: author id, author, affiliations, index keywords, references, and author keywords. That way later on I can work with those pieces separately.
# identifying tiles, abstracts, author keywords and index keywords with my own keywords
## keywords: Replication crisis, replication crisis, Replicability crisis, replicability crisis, Reproducibility crisis, reproducibility crisis
data.title <- data %>%
filter(grepl("Neural network|Neural networks|artificial neural network|artificial neural networks", title, ignore.case = TRUE))
data.abstract <- data %>%
filter(grepl("Neural network|Neural networks|artificial neural network|artificial neural networks", abstract, ignore.case = TRUE))
data.author.keywords <- data %>%
filter(grepl("Neural network|Neural networks|artificial neural network|artificial neural networks", author.keywords, ignore.case = TRUE))
data.index.keywords <- data %>%
filter(grepl("Neural network|Neural networks|artificial neural network|artificial neural networks", index.keywords, ignore.case = TRUE))
#BINDING WITH THE EXTRA COLUMNS
#putting all of the categories back together
data.networks <- do.call("rbind", list(data.title, data.abstract, data.author.keywords, data.index.keywords))
#deleting any articles that might have replicated
data.networks <- data.networks %>%
distinct(id, .keep_all = TRUE)
#splitting author.id,
##in to separate columns using the splitstackshape library, which doesn't require you to know the total a column needs to be split in
data.networks <- cSplit(data.networks, "author.id", sep=";")
data.networks <- cSplit(data.networks, "authors", sep=",")
data.networks <- cSplit(data.networks, "affiliations", sep=";")
data.networks <- cSplit(data.networks, "index.keywords", sep=";")
data.networks <- cSplit(data.networks, "references", sep=";")
data.networks <- cSplit(data.networks, "author.keywords", sep=";")
The fist figure shows what year items relating to neural networks are published in Science from 2010-2020.
#number of items by year
number.volumes.networks <- data.networks %>%
count(year)
#renaming
names(number.volumes.networks) <- c("year", "n.items.by.year")
#calculating the number of items by issue
number.issues.networks <- data.networks %>%
group_by(year) %>%
count(issue)
#renaming
names(number.issues.networks) <- c("year", "issue", "n.items.by.issue")
#looking at the ARTICLE information by year
issues.by.year.bar.networks <- ggplot(number.volumes.networks) +
geom_line(aes(x= year, y = n.items.by.year), color = "#5F8495") +
scale_x_continuous(breaks = c(2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020)) +
# scale_y_continuous(breaks = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) +
xlab("Year") +
ylab("Number of items") +
#labs(title = "") +
theme_classic()
issues.by.year.bar.networks

The next figure visualizes the number of items published in Science relating to neural networks by issue, also indicated by year.
#counting number of articles related to neural networks by issue (54)
issues.of.networks <- data.networks %>%
group_by(issue) %>%
count(issue, .drop = FALSE)
#getting a list of all issues (569)
all.issues <- number.issues %>%
ungroup() %>%
select(-year, -n.items.by.issue) %>%
mutate(n = 0)
#filtering out the issues that have neural network information in them (515/512)
number.issues.networks <- all.issues %>%
filter(!(issue %in% issues.of.networks$issue))
#adding the databases above together (counted articles related to neural networks and the ones that don't, with 0 numbers)
year.count <- rbind(number.issues.networks, issues.of.networks)
issues.by.year.bar <- ggplot(year.count) +
geom_line(aes(x= issue, y = n), color = "#406343") +
scale_y_continuous(breaks = c(0, 1, 2, 3, 4, 5, 6)) +
scale_x_continuous(breaks = c(5900, 6000, 6100, 6200, 6300, 6400, 6500, 6600, 6700, 6800, 6900)) +
xlab("Issue number") +
ylab("Number of items") +
ggtitle("Fig 6. Number of published items related to neural networks by issue in Science, 2010-2020") +
theme(plot.title = element_text(size = 12)) +
#20109
ggplot2::annotate("segment", x = 5961, xend = 5961, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 5961, y = 6, label = "2010", color = "#99A799") +
#2011
ggplot2::annotate("segment", x = 6013, xend = 6013, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6013, y = 6, label = "2011", color = "#99A799") +
#2012
ggplot2::annotate("segment", x = 6064, xend = 6064, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6064, y = 6, label = "2012", color = "#99A799") +
#2013
ggplot2::annotate("segment", x = 6115, xend = 6115, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6115, y = 6, label = "2013", color = "#99A799") +
#2014
ggplot2::annotate("segment", x = 6166, xend = 6166, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6166, y = 6, label = "2014", color = "#99A799") +
#2015
ggplot2::annotate("segment", x = 6217, xend = 6217, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6217, y = 6, label = "2015", color = "#99A799") +
#2016
ggplot2::annotate("segment", x = 6268, xend = 6268, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6268, y = 6, label = "2016", color = "#99A799") +
#2017
ggplot2::annotate("segment", x = 6320, xend = 6320, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6320, y = 6, label = "2017", color = "#99A799") +
#2018
ggplot2::annotate("segment", x = 6371, xend = 6371, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6371, y = 6, label = "2018", color = "#99A799") +
#2019
ggplot2::annotate("segment", x = 6422, xend = 6422, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6422, y = 6, label = "2019", color = "#99A799") +
#2020
ggplot2::annotate("segment", x = 6473, xend = 6473, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
ggplot2::annotate("text", x = 6473, y = 6, label = "2020", color = "#99A799")
issues.by.year.bar + theme_classic()

Next is a histogram of number of citations recieved by neural network items from Science 2010-2020.
#descriptive visualization
## one: histogram of the citation, bins with 30 counts
citation.hist <- ggplot(data.networks, aes(x=cited.by)) +
geom_histogram(fill = "#406343", binwidth= 30, center = 0.1) +
scale_x_continuous(breaks = c(0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900)) +
xlab("Citation counts") +
ylab("Number of articles") +
labs(title = "Fig 8. Distribution of amount of citations received by neural network items")
citation.hist + theme_classic()

To view the histogram distribution more clearly, I also ran a version that excluded the outliers (which I categorizes as over 500 citations)
#two: visualization of the citation counts excluding outliers (<500)
## binwidth 10
data.networks.citation.most <- data.networks %>%
filter(cited.by < 500)
citation.hist.most <- ggplot(data.networks.citation.most, aes(x=cited.by)) +
geom_histogram(binwidth = 30, fill = "#406343") +
# scale_x_continuous(breaks = c(10, 50, 100, 150, 200, 250, 300, 350, 400,
# 450, 500, 550, 600, 650, 700, 750, 800)) +
xlab("Citation counts, without outliers") +
ylab("Number of articles") +
labs(title = "Fig 9. Distribution of ammount of citations recieved by neural network items, excluding outliers (500)") +
theme(plot.title = element_text(size = 11))
citation.hist.most + theme_classic()

The following pie chart categorizes what items have or do not have abstract information.
#pie chart of the percentage of articles with no articles
#checking how many articles are missing abstracts
#total articles missing abstracts = 13210
data.nn.no.abstract <- data.networks %>%
filter(is.na(abstract)) %>% #filtering those rows in abstract that have NA
mutate(has.abstract = "No")
data.nn.yes.abstract <- data.networks %>%
filter(!(id %in% data.nn.no.abstract$id)) %>% #filtering out those articles already categorized as NA
mutate(has.abstract = "Yes")
data.nn.abstract.both <- rbind(data.nn.no.abstract, data.nn.yes.abstract)
data.nn.abstracts <- data.nn.abstract.both %>%
group_by(has.abstract) %>%
count(has.abstract) %>%
ungroup() %>%
mutate(per = (100*n)/sum(n))
data.nn.abstracts$per <- round(data.nn.abstracts$per)
ggplot(data.nn.abstracts, aes(x="", y = has.abstract, fill = has.abstract, palette = "BuGn")) +
geom_col() +
theme_void() +
theme(axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank(),
panel.grid = element_blank()) +
coord_polar("y", start = 0) +
scale_fill_brewer(palette = "pal5") +
geom_text(aes(label = paste0(per,"%")), position = position_stack(vjust=0.5)) +
ggtitle("Fig 10. Percentages of items about neural networks
with or without abstracts in Science 2010-2020") +
theme(plot.title = element_text(size = 12)) +
guides(fill = guide_legend(title = "Has Abstract"))
Unknown palette pal5

The next figure is a distribution of document types about neural networks and whether they have abstracts in Science 2010-2020.
#checking by document type what things are missing abstracts
nn.abstract.types <- ggplot(data.nn.abstract.both, aes(x = document.type, fill = has.abstract, palette = "BuGn")) +
geom_bar() +
xlab("Kinds of documents") +
ylab("Amount with or without abstract information") +
theme_classic() +
scale_fill_brewer(palette = "BuGn") +
guides(fill = guide_legend(title = "Has Abstract")) +
ggtitle("Fig 11. Distribution of document types about neural networks and wether
they have abstracts in Science 2010-2020") +
theme(plot.title = element_text(size = 12))
#tilting the text so it is readable and moving downwards
nn.abstract.types + theme(axis.text.x = element_text(angle = 45, hjust = 1))

The next figure is a word cloud of the most common words in the abstract, including common words.
#making a long list of all the keywords used in articles about neural networks
index.keywords <- data.networks %>%
select(index.keywords_01:index.keywords_66, id)
index.keywords = melt(index.keywords,id.vars=c("id"))
#making everything lowercase
index.keywords$value = tolower(index.keywords$value)
index.keywords <- index.keywords %>%
select(-id, -variable) %>%
drop_na(value) %>%
count(value)
wordcloud(words = index.keywords$value, freq = index.keywords$n, min.freq = 5,
max.words=200, random.order=FALSE, rot.per=0.35,
colors=brewer.pal(8, "Dark2"), scale=c(2.0,0.25))

To more clearly see the words of interest, I excluded some of the words that are more common in the English language and therefore might be less indicative of what the abstracts are about. The keywords I excluded were: the, of, and, in, a, to, for, that, we, is, by, with, this, are, on, an, can, from, all, ©, be, which, how, or, our, it.
#making wordcloud of the abstract information
abstract.words <- data.networks %>%
select(id, abstract) %>%
drop_na(abstract)
#taking away punctuation
abstract.words$abstract <- gsub('[[:punct:] ]+',' ', as.character(abstract.words$abstract))
#making whole text lowercase
abstract.words$abstract = tolower(abstract.words$abstract)
#separating column out in to individual words
abstract.words <- cSplit(abstract.words, "abstract", sep=" ")
#trimming leading and trailing whitespace
trimws_df <- function(x, ...){
x[] <- lapply(x, trimws, ...)
x
}
abstract.words <- trimws_df(abstract.words)
#combining in to one column
abstract.words = melt(abstract.words, id.vars=c("id"))
#counting the number of words
abstract.words <- abstract.words %>%
select(-id, -variable) %>%
drop_na(value) %>%
count(value)
#making a word cloud including all the words
wordcloud(words = abstract.words$value, freq = abstract.words$n, min.freq = 3,
max.words=200, random.order=FALSE, rot.per=0.35, scale=c(5.0,0.5),
colors=brewer.pal(8, "Dark2"))

#removing common words
abstract.words <- abstract.words[!grepl("the|of|and|in|a|to|for|that|we|is|by|with|this|are|on|an|can|from|all|©|be|which|how|or|our|it", abstract.words$value),]
#making word cloud
wordcloud(words = abstract.words$value, freq = abstract.words$n, min.freq = 3,
max.words=200, random.order=FALSE, rot.per=0.35,
colors=brewer.pal(8, "Dark2"), scale=c(3.0,0.25))

I selected 4 articles randomly to qualitatively code. Two were totally random and I got: ⁃ Neural scene representation and rendering, 2018. Vol 360, issue 6394. doi: 10.1126/science.aar6170 ⁃ The biochemical basis of microRNA targeting efficacy, 2019. Vol 366. doi: 10.1126/science.aav1741 One was from the top 25% of citations received (more than 171.5 citations) ⁃ Terrestrial gross carbon dioxide uptake: Global distribution and covariation with climate. doi: 10.1126/science.1184984 One was randomly selected from the year with the most articles about neural networks (2019) ⁃ Machine learning transforms how microstates are sampled, 2019. Vol 365. Issue 6457. doi: 10.1126/science.aay2568 As a note, this will return different articles every time it is run. I’ve selected the articles that appeared the first time.
#randomly selecting articles to close read
##note, this will return different articles every time it is run. I've selected the articles that appeared the first time.
#randomly selecting 2 articles from the whole networks database
sample_n(data.networks, 2)
#selected: Neural scene representation and rendering, 2018. Vol 360, issue 6394. doi: 10.1126/science.aar6170
#selected: The biochemical basis of microRNA targeting efficacy, 2019. Vol 366. doi: 10.1126/science.aav1741
#randomly selecting 1 article within the top 25% number of citations
## extracting the quantiles of the dataset, upper 75% = 171.5
quantile(data.networks$cited.by, na.rm=TRUE)
0% 25% 50% 75% 100%
1.0 8.5 58.5 171.5 1831.0
data.networks.top.75per <- data.networks %>%
filter(cited.by > 171.5)
sample_n(data.networks.top.75per,1)
#selected: Terrestrial gross carbon dioxide uptake: Global distribution and covariation with climate. doi: 10.1126/science.1184984
#randomly selecting 1 article from 2019 (the year with the most articles published)
data.networks.2019 <- data.networks %>%
filter(year == "2019")
sample_n(data.networks.2019, 1)
#selected: Machine learning transforms how microstates are sampled, 2019. Vol 365. Issue 6457. doi: 10.1126/science.aay2568
LS0tCnRpdGxlOiAiVXNhZ2Ugb2YgdGVybSAnTmV1cmFsIE5ldHdvcmsnIGluIFNjaWVuY2UgMjAxMC0yMDIwIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpUaGlzIGlzIGFuIFIgTm90ZWJvb2sgd2hpY2ggZGVzY3JpYmVzIHRoZSBkaXN0YW50IHJlYWRpbmcgcHJvY2VzcyB1c2VkIGZvciBteSBwcm9qZWN0LiBUaGVyZSBhcmUgYnJpZWYgZGVzY3JpcHRvcnMgYWJvdmUgZWFjaCBjb2RlIGNodW5rIHdoaWNoIGRlc2NyaWJlIHdoYXQgd2FzIGRvbmUsIHdpdGggbW9yZSBkZXRhaWxlZCBjb21tZW50YXJ5IGluIHRoZSBjb2Rpbmcgc2VjdGlvbnMgd2hpY2ggYXJlIG5vdGVkIHdpdGggYSAiIyIgc2lnbi4gRG93bmxvYWRpbmcgdGhlIHdob2xlIGZvbGRlciAiTmV1cmFsIE5ldHdvcmsgVXNhZ2UgaW4gU2NpZW5jZSIgYW5kIG9wZW5pbmcgaW4gU3R1ZGlvIFIgd2lsbCBsZXQgeW91IHJ1biB0aGlzIGNvZGUgb24geW91ciBvd24uCgpPbmNlIHRoZSBkYXRhYmFzZSB3YXMgZG93bmxvYWRlZCwgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIGluIHRoZSBtZXRob2RvbG9neSBzZWN0aW9uLCBJIGxvYWQgYWxsIHRoZSBkYXRhYmFzZXMgZnJvbSBkaWZmZXJlbnQgeWVhcnMuIEkgZHJvcHBlZCB0aGUgY29sdW1ucyB0aGF0IHdlcmVuJ3Qgb2YgaW50ZXJlc3QgYW5kIHJlbmFtZWQgdGhvc2UgdGhhdCB3ZXJlIGZvciBlYXNpZXIgdXNlLiBKdXN0IGluY2FzZSBvZiBkdXBsaWNhdGVzLCBJIGV4dHJhY3RlZCB0aGUgdW5pcXVlIGluc3RhbmNlcyBvZiByb3dzLiBJIGRpc2NhcmRlZCBkdXBsaWNhdGUgcm93cyBhbmQgY29sdW1ucyB0aGF0IGNvbnRhaW5lZCBubyBpbmZvcm1hdGlvbiBhdCBhbGwuIEkgY3JlYXRlZCBhIHVuaXF1ZSBJRCBwZXIgYXJ0aWNsZSB0byBtYWtlIGlkZW50aWZ5aW5nIHNwZWNpZmljIGFydGljbGVzIGVhc2llciB0byBmaW5kIGlmIG5lY2Vzc2FyeS4gV2hlbiBkYXRhIHdhc27igJl0IGF2YWlsYWJsZSwgU2NvcHVzIHVzZWQgYSB0ZXh0IG9mIOKAnFt4IGNhdGVnb3J5IGlzIG5vdCBhdmFpbGFibGVd4oCdIGluc3RlYWQgb2YganVzdCDigJxOQeKAnS4gVG8gY29udmVydCB0byBOQSBzZWN0aW9ucywgSSBmaWx0ZXJlZCBmb3Igcm93cyB0aGF0IGNvbnRhaW5lZCDigJxhdmFpbGFibGVd4oCdIGFuZCBjb3BpZWQgdGhlIG1lc3NhZ2UgcHJlY2lzZWx5LiBUaGF0IHdheSBJIGVxdWF0ZWQgdGhlIG1lc3NhZ2UgdG8gYW4g4oCcTkHigJ0gdGV4dCBmb3IgZWFzaWVyIHVzYWdlLgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI2xvYWRpbmcgdGhlIG5lY2VzYXJ5IHBhY2thZ2VzIGZvciB0aGlzIGNvZGUKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoc2tpbXIpCmxpYnJhcnkoc3BsaXRzdGFja3NoYXBlKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoamNvbG9ycykKbGlicmFyeSh3b3JkY2xvdWQpCmxpYnJhcnkod29yZGNsb3VkMikKbGlicmFyeSh0bSkKbGlicmFyeShkYXRhLnRhYmxlKQoKI2xvYWRpbmcgdGhlIGNzdiBmaWxlcyBhbmQgdGhlbiBqb2luaW5nIHRoZW0gaW4gdG8gb25lIGRhdGEgYmFzZQogICMjY29udmVydGluZyBibGFua3MgaW4gdG8gTkEKCiMyMDEwIGRhdGEgYmFzZXMKZGF0YS4xMC5vIDwtIHJlYWQuY3N2ICgiMjAxMF9ub19hcnRpY2xlcy5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCmRhdGEuMTAuYSA8LSByZWFkLmNzdiAoIjIwMTBfeWVzX2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDExIGRhdGEgYmFzZXMKZGF0YS4xMS5vIDwtIHJlYWQuY3N2ICgiMjAxMV9ub19hcnRpY2xlcy5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCmRhdGEuMTEuYSA8LSByZWFkLmNzdiAoIjIwMTFfeWVzX2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDEyIGRhdGFiYXNlcwpkYXRhLjEyLm8gPC0gcmVhZC5jc3YgKCIyMDEyX25vX2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKZGF0YS4xMi5hIDwtIHJlYWQuY3N2ICgiMjAxMl95ZXNfYXJ0aWNsZXMuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQoKIzIwMTMgZGF0YWJhc2VzCmRhdGEuMTMubyA8LSByZWFkLmNzdiAoIjIwMTNfbm9fYXJ0aWNsZXMuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQpkYXRhLjEzLmEgPC0gcmVhZC5jc3YgKCIyMDEzX2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDE0IGRhdGFiYXNlcwpkYXRhLjE0LmEgPC0gcmVhZC5jc3YgKCIyMDE0X2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKZGF0YS4xNC5vIDwtIHJlYWQuY3N2ICgiMjAxNF9vdGhlci5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCgojMjAxNSBkYXRhYmFzZXMKZGF0YS4xNS5hIDwtIHJlYWQuY3N2ICgiMjAxNV9hcnRpY2xlcy5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCmRhdGEuMTUubyA8LSByZWFkLmNzdiAoIjIwMTVfb3RoZXIuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQoKIzIwMTYgZGF0YWJhc2UKICAjIyBldmVyeXRoaW5nIGZpdCBpbiBvbmUgZm9yIDIwMTYKZGF0YS4xNi5hbGwgPC0gcmVhZC5jc3YgKCIyMDE2X2FsbC5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCgojMjAxNyBkYXRhYmFzZQogICMjIGV2ZXJ5dGhpbmcgZmlyIGluIG9uZSBmb3IgMjAxNwpkYXRhLjE3LmFsbCA8LSByZWFkLmNzdiAoIjIwMTdfYWxsLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDE4IGRhdGFiYXNlCmRhdGEuMTguYSA8LSByZWFkLmNzdiAoIjIwMThfYXJ0aWNsZXMuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQpkYXRhLjE4Lm8gPC0gcmVhZC5jc3YgKCIyMDE4X290aGVyLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDE5IGRhdGFiYXNlCmRhdGEuMTkuYSA8LSByZWFkLmNzdiAoIjIwMTlfYXJ0aWNsZXMuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQpkYXRhLjE5Lm4gPC0gcmVhZC5jc3YgKCIyMDE5X25vdGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKZGF0YS4xOS5vIDwtIHJlYWQuY3N2ICgiMjAxOV9vdGhlci5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCgojMjAyMCBkYXRhYmFzZQpkYXRhLjIwLm4gPC0gcmVhZC5jc3YgKCIyMDIwX25vdGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKZGF0YS4yMC5vIDwtIHJlYWQuY3N2ICgiMjAyMF9vdGhlcl9hcnRpY2xlcy5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCgojcHV0dGluZyB0aGUgZGF0YWJhc2VzIHRvZ2V0aGVyIGludG8gb25lCmRhdGEub3JpZ2luYWwgPC0gcmJpbmQoZGF0YS4xMC5hLCBkYXRhLjEwLm8sCiAgICAgICAgICBkYXRhLjExLmEsIGRhdGEuMTEubywgCiAgICAgICAgICBkYXRhLjEyLmEsIGRhdGEuMTIubywgCiAgICAgICAgICBkYXRhLjEzLmEsIGRhdGEuMTMuYSwKICAgICAgICAgIGRhdGEuMTQuYSwgZGF0YS4xNC5vLAogICAgICAgICAgZGF0YS4xNS5hLCBkYXRhLjE1Lm8sCiAgICAgICAgICBkYXRhLjE2LmFsbCwKICAgICAgICAgIGRhdGEuMTcuYWxsLAogICAgICAgICAgZGF0YS4xOC5vLCBkYXRhLjE4LmEsCiAgICAgICAgICBkYXRhLjE5LmEsIGRhdGEuMTkubiwgZGF0YS4xOS5vLAogICAgICAgICAgZGF0YS4yMC5uLCBkYXRhLjIwLm8pCgojY2xlYW5pbmcgdGhlIGNzdiBmaWxlCiAgIyMgZGlzY2FyZGluZyBzb21lIG9mIHRoZSBjb2x1bW5zIHRoYXQgd29uJ3QgYmUgdXNlZAogICMjIHJlbmFtaW5nIHRoZSBjb2x1bW4gdGl0bGVzIHNvIHRoZXkncmUgbm90IGNhcGl0YWxpemVkCiAgIyMgY29udmVydGluZyBsYWNrIG9mIGluZm9ybWF0aW9uIG5vdGVzIGluIHRvIE5BIHN0cmluZ3MKICAjIyBhZGRpbmcgYW4gaWQgdG8gZWFjaCBjb2x1bW4KCmRhdGEub3JpZ2luYWwgPC0gZGF0YS5vcmlnaW5hbCAlPiUKIHNlbGVjdCgtQXJ0Li5Oby4sIC1Nb2xlY3VsYXIuU2VxdWVuY2UuTnVtYmVycywgLUNoZW1pY2Fscy5DQVMsLVRyYWRlbmFtZXMsIC1NYW51ZmFjdHVyZXJzLCAtRnVuZGluZy5UZXh0LjEsIC1GdW5kaW5nLlRleHQuMiwgLUZ1bmRpbmcuVGV4dC4zLCAtRnVuZGluZy5UZXh0LjQsIC1GdW5kaW5nLlRleHQuNSwgLUZ1bmRpbmcuVGV4dC42LCAtRnVuZGluZy5UZXh0LjcsIC1GdW5kaW5nLlRleHQuOCwgLUZ1bmRpbmcuVGV4dC45LCAtRnVuZGluZy5UZXh0LjEwLCAtQ29ycmVzcG9uZGVuY2UuQWRkcmVzcywgIC1BYmJyZXZpYXRlZC5Tb3VyY2UuVGl0bGUpCgojcmVuYW1pbmcgdGhlIGNvbHVtbnMgZm9yIGVhc2llciBoYW5kbGluZwpuYW1lcyhkYXRhLm9yaWdpbmFsKSA8LSBjKCJhdXRob3JzIiwgImF1dGhvci5pZCIsICJ0aXRsZSIsICJ5ZWFyIiwgInNvdXJjZS50aXRsZSIsICJ2b2x1bWUiLCAiaXNzdWUiLCAicGFnZS5zdGFydCIsICJwYWdlLmVuZCIsICJwYWdlLmNvdW50IiwgImNpdGVkLmJ5IiwgImRvaSIsICJsaW5rIiwgImFmZmlsaWF0aW9ucyIsICJhdXRob3IuYWZmaWxpYXRpb25zIiwgImFic3RyYWN0IiwgImF1dGhvci5rZXl3b3JkcyIsICJpbmRleC5rZXl3b3JkcyIsICJmdW5kaW5nLmRldGFpbHMiLCAicmVmZXJlbmNlcyIsICJlZGl0b3JzIiwgInNwb25zb3JzIiwgInB1Ymxpc2hlciIsICJjb25mZXJlbmNlLm5hbWUiLCAiY29uZmVyZW5jZS5kYXRlIiwgImNvbmZlcmVuY2UubG9jYXRpb24iLCAiY29uZmVyZW5jZS5jb2RlIiwgImlzc24iLCAiaXNibiIsICJjb2RlbiIsICJwdWJtZWQuaWQiLCAib3JpZ2luYWwubGFuZ3VhZ2UiLCAiZG9jdW1lbnQudHlwZSIsICJwdWJsaWNhdGlvbi5zdGFnZSIsICJvcGVuLmFjY2VzcyIsICJzb3VyY2UiLCAiZWlkIikKCiNleHRyYWN0aW5nIHRoZSB1bmlxdWUgaW5zdGFuY2VzCmRhdGEub3JpZ2luYWwgPC0gdW5pcXVlKGRhdGEub3JpZ2luYWwpCgojY2hlY2tpbmcgaG93IG1hbnkgTkFzIGV4aXN0IHdpdGhpbiBlYWNoIGNvbHVtbgpjb2xTdW1zKGlzLm5hKGRhdGEub3JpZ2luYWwpKQoKI2FsbCBjb2x1bW5zIChleGNlcHQgaXNibikgYXJlIHRvdGFsbHkgZW1wdHkgY29sdW1ucwogICNpc2JuIGhhcyBvbmUgMSByb3cgd2l0aCBkYXRhCmRhdGEub3JpZ2luYWwgPC0gZGF0YS5vcmlnaW5hbCAlPiUKIHNlbGVjdCgtZWRpdG9ycywgLXNwb25zb3JzLCAtY29uZmVyZW5jZS5uYW1lLCAtY29uZmVyZW5jZS5kYXRlLCAtY29uZmVyZW5jZS5sb2NhdGlvbiwgLWNvbmZlcmVuY2UuY29kZSkKCiNhZGRpbmcgYSB1bmlxdWUgaWQgY29kZSBmb3IgYWxsIG9mIHRoZSBjb2x1bW5zCmRhdGEgPC0gZGF0YS5vcmlnaW5hbCAlPiUKICBtdXRhdGUoaWQgPSByb3dfbnVtYmVyKCkpCgojY2hlY2tpbmcgd2hpY2ggY29sdW1ucyB1c2UgIltObyB4IGF2YWlsYWJsZV0iIGZvcm1hdAogICMjdG8gYmUgYWJsZSB0byBjb3B5IHRoYXQgZm9ybWF0IGFuZCByZXBsYWNlIHdpdGggTkEgaW5zdGVhZAoKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgYXV0aG9ycykpCiNbTm8gYXV0aG9yIG5hbWUgYXZhaWxhYmxlXQoKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgYXV0aG9yLmlkKSkKI1tObyBhdXRob3IgaWQgYXZhaWxhYmxlXQoKI25vbmUgb2YgdGhlc2UgaGF2ZSBpbnNlcnRlZCBjYXRlZ29yaWVzCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHRpdGxlKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgeWVhcikpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHNvdXJjZS50aXRsZSkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHZvbHVtZSkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGlzc3VlKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgcGFnZS5zdGFydCkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHBhZ2UuZW5kKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgcGFnZS5jb3VudCkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGNpdGVkLmJ5KSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgZG9pKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgbGluaykpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGFmZmlsaWF0aW9ucykpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGF1dGhvci5hZmZpbGlhdGlvbnMpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBhYnN0cmFjdCkpCiNbTm8gYWJzdHJhY3QgYXZhaWxhYmxlXQoKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgYXV0aG9yLmtleXdvcmRzKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgaW5kZXgua2V5d29yZHMpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBmdW5kaW5nLmRldGFpbHMpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCByZWZlcmVuY2VzKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgcHVibGlzaGVyKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgaXNzbikpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGlzYm4pKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBjb2RlbikpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHB1Ym1lZC5pZCkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIG9yaWdpbmFsLmxhbmd1YWdlKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgZG9jdW1lbnQudHlwZSkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHB1YmxpY2F0aW9uLnN0YWdlKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgb3Blbi5hY2Nlc3MpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBzb3VyY2UpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBlaWQpKQoKI3JlcGxhY2luZyB0ZXh0IGFib3V0IG1pc3NpbmcgZGF0YSBmb3IgTkEgaW5zdGVhZCBpbiB0aGUgY29sdW1ucyB0aGF0IHVzZSB0ZXh0IHRvIGluZGljYXRlIG1pc3NpbmcgaW5mb3JtYXRpb24KZGF0YSA8LSBkYXRhICU+JQogIG11dGF0ZShhdXRob3JzID0gbmFfaWYoYXV0aG9ycywgIltObyBhdXRob3IgbmFtZSBhdmFpbGFibGVdIikpICU+JQogIG11dGF0ZShhdXRob3IuaWQgPSBuYV9pZihhdXRob3IuaWQsICJbTm8gYXV0aG9yIGlkIGF2YWlsYWJsZV0iKSkgJT4lCiAgbXV0YXRlKGFic3RyYWN0ID0gbmFfaWYoYWJzdHJhY3QsICJbTm8gYWJzdHJhY3QgYXZhaWxhYmxlXSIpKQpgYGAKClRvIG9idGFpbiB0aGUgdmlzdWFsaXphdGlvbnMgYWJvdXQgdGhlIGluZm9ybWF0aW9uIG9mIGFsbCBpdGVtcyBpbiBTY2llbmNlIGZyb20gMjAxMC0yMDIwLCBJIGNhbGN1bGF0ZWQgdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbjogbnVtYmVyIG9mIGlzc3VlcyBieSB5ZWFyLCBob3cgbWFueSBpdGVtcyBwZXIgdm9sdW1lLCBhbmQgbnVtYmVyIG9mIGl0ZW1zIGJ5IGlzc3VlLgoKYGBge3J9CiNjYWxjdWxhdGluZyB0aGUgbnVtYmVyIG9mIGl0ZW1zIGJ5IGlzc3VlCm51bWJlci52b2x1bWVzIDwtIGRhdGEgJT4lIAogIGNvdW50KHllYXIpCiNyZW5hbWluZwpuYW1lcyhudW1iZXIudm9sdW1lcykgPC0gYygieWVhciIsICJuLml0ZW1zLmJ5LnllYXIiKQoKI2NhbGN1bGF0aW5nIHRoZSBudW1iZXIgb2YgaXRlbXMgYnkgaXNzdWUKbnVtYmVyLmlzc3VlcyA8LSBkYXRhICU+JSAKICBncm91cF9ieSh5ZWFyKSAlPiUKICBjb3VudChpc3N1ZSkKI3JlbmFtaW5nCm5hbWVzKG51bWJlci5pc3N1ZXMpIDwtIGMoInllYXIiLCAiaXNzdWUiLCAibi5pdGVtcy5ieS5pc3N1ZSIpCgojZXhwb3J0aW5nIGNzdiBmaWxlIGZvciB3cml0ZSB1cAp3cml0ZS5jc3YobnVtYmVyLmlzc3VlcywgIkl0ZW1zX2J5X2lzc3VlLmNzdiIpCgojY2FsY3VsYXRpbmcgdGhlIG51bWJlciBvZiBpc3N1ZSBieSB5ZWFyCm51bWJlci5pc3N1ZXMuYnkueWVhciA8LSBkYXRhICU+JQogIGdyb3VwX2J5KHllYXIpICU+JQogIGNvdW50KGlzc3VlKSAlPiUKICBzZWxlY3QoeWVhciwgaXNzdWUpICU+JQogIGNvdW50KHllYXIpCgp3cml0ZS5jc3YobnVtYmVyLmlzc3Vlcy5ieS55ZWFyLCAiSXRlbXNfYnlfeWVhci5jc3YiKQoKI3JlbmFtaW5nIHRoZSBjb2x1bW4gdG8gYmUgcmVwcmVzZW50YXRpdmUgb2YgY29udGVudCwgbnVtYmVyIG9mIGl0ZW1zCm5hbWVzKG51bWJlci5pc3N1ZXMuYnkueWVhcikgPC0gYygieWVhciIsICJuLm9mLmlzc3VlcyIpCmBgYAoKVGhlIGZpcnN0IGdyYXBoIHJlcHJlc2VudHMgdGhlIGRpc3RyaWJ1dGlvbiBvZiBpdGVtcyBwdWJsaXNoZWQgaW4gc2NpZW5jZSBieSB5ZWFyLgpgYGB7cn0KI2dyYXBoIG9mIHRoZSBOVU1CRVIgT0YgaXNzdWVzIEJZIFlFQVIgb2YgYWxsIHNjaWVuY2UgYXJ0aWNsZXMgMjAxMC0yMDIwCmlzc3Vlcy5ieS55ZWFyLmJhciA8LSBnZ3Bsb3QobnVtYmVyLnZvbHVtZXMpKwogIGdlb21fbGluZShhZXMoeD0geWVhciwgeSA9IG4uaXRlbXMuYnkueWVhciksIGNvbG9yID0gIiM1Rjg0OTUiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMjAxMCwgMjAxMSwgMjAxMiwgMjAxMywgMjAxNCwgMjAxNSwgMjAxNiwgMjAxNywgMjAxOCwgMjAxOSwgMjAyMCkpICsKICB4bGFiKCJZZWFyIikgKyAKICB5bGFiKCJOdW1iZXIgb2YgaXRlbXMiKSArCiAgbGFicyh0aXRsZSA9ICJGaWcgMy4gRGlzdHJpYnV0aW9uIG9mIGFtb3VudCBvZiBpdGVtcyBwdWJsaXNoZWQgaW4gc2NpZW5jZSBieSB5ZWFyLCAyMDEwLTIwMjAiKSArCiAgdGhlbWVfY2xhc3NpYygpCgppc3N1ZXMuYnkueWVhci5iYXIKYGBgCgpUaGUgc2Vjb25kIGZpZ3VyZSBpcyBhIGhpc3RvZ3JhbSBvZiBob3cgbWFueSBjaXRhdGlvbnMgYXJ0aWNsZXMgaW4gU2NpZW5jZSByZWNlaXZlZCBmcm9tIDIwMTAtMjAyMCwgd2l0aCBhIGJpbiB3aWR0aCBvZiAzMCB1bml0cy4KYGBge3J9CiN2aXN1YWxpemluZyBkaXN0cmlidXRpb24gb2YgdGhlIGNpdGF0aW9uIGNvdW50cyBmb3IgQUxMIGFydGljbGVzIGluIHNjaWVuY2UKI2Rlc2NyaXB0aXZlIHZpc3VhbGl6YXRpb24KICAjIyBvbmU6IGhpc3RvZ3JhbSBvZiB0aGUgY2l0YXRpb24sIGJpbnMgd2l0aCAzMCBjb3VudHMKY2l0YXRpb24uaGlzdC5hbGwgPC0gZ2dwbG90KGRhdGEsIGFlcyh4PWNpdGVkLmJ5KSkgKwogIGdlb21faGlzdG9ncmFtKGZpbGwgPSAiIzVGODQ5NSIsIGJpbndpZHRoPSAzMCwgY2VudGVyID0gMC4xKSArCiAgeGxhYigiTnVtYmVyIG9mIGNpdGF0aW9ucyBpdGVtcyByZWNpZXZlZCIpICsgCiAgeWxhYigiTnVtYmVyIG9mIGl0ZW1zIikgKwogIGxhYnModGl0bGUgPSAiRmlnIDEuIERpc3RyaWJ1dGlvbiBvZiBudW1iZXIgb2YgY2l0YXRpb25zIHJlY2lldmVkIGJ5IGl0ZW1zIAogICAgICAgcHVibGlzaGVkIGluIFNjaWVuY2UsIDIwMTAtMjAyMCIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkpCgpjaXRhdGlvbi5oaXN0LmFsbCArIHRoZW1lX2NsYXNzaWMoKQpgYGAKCk5leHQsIEkgY2FsY3VsYXRlZCB3aGljaCBpc3N1ZSBzdGFydHMgZWFjaCB5ZWFyLiBUaGF0IHdheSBsYXRlciBJIGNhbiBhZGQgeWVhciBjYXRlZ29yaWVzIHRvIHRoZSBmaWd1cmUgYWJvdXQgYW1vdW50IG9mIGl0ZW1zIHB1Ymxpc2hlZCBieSBpc3N1ZS4KYGBge3J9CiNjYWxjdWxhdGluZyB0aGUgZmlyc3QgaXNzdWUgbnVtYmVyIG9mIGVhY2ggeWVhciB0byBhZGQgbGFiZWxzIHRvIHRoZSBsYXRlciBncmFwaApudW1iZXIuaXNzdWVzICU+JQogIGdyb3VwX2J5KHllYXIpICU+JQogIHNsaWNlX2hlYWQobiA9IDEpCmBgYAoKVXNpbmcgdGhlIGluZm9ybWF0aW9uIGdhdGhlcmVkIGFib3ZlIEkgbWFkZSBhIGdyYXBoIG9mIG51bWJlciBvZiBpdGVtcyBwdWJsaXNoZWQgYnkgaXNzdWUsIG5vdGluZyB3aGVyZSBlYWNoIHllYXIgc3RhcnRzLgpgYGB7cn0KI3RyYWNraW5nIHRoZSBudW1iZXIgb2YgYXJ0aWNsZXMgYWJvdXQgbmV1cmFsIG5ldHdvcmtzIHRocm91Z2ggdGhlIGlzc3VlcyBpbiBzY2llbmNlCmlzc3Vlcy5ieS55ZWFyLmJhciA8LSBnZ3Bsb3QobnVtYmVyLmlzc3VlcykgKwogIGdlb21fbGluZShhZXMoeD0gaXNzdWUsIHkgPSBuLml0ZW1zLmJ5Lmlzc3VlKSwgY29sb3IgPSAiIzVGODQ5NSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYyg1OTAwLCA2MDAwLCA2MTAwLCA2MjAwLCA2MzAwLCA2NDAwLCA2NTAwLCA2NjAwLCA2NzAwLCA2ODAwLCA2OTAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsIDE1LCAzMCwgNDUsIDYwLCA3NSwgOTAsIDEwNSwgMTIwLCAxMzUsIDE1MCkpICsKICB4bGFiKCJJc3N1ZSBudW1iZXIiKSArIAogIHlsYWIoIk51bWJlciBvZiBpdGVtcyBieSBpc3N1ZSIpICsKICBsYWJzKHRpdGxlID0gIkZpZyAyLiBEaXN0cmlidXRpb24gb2YgbnVtYmVyIG9mIGl0ZW1zIHB1Ymxpc2hlZCBpbiBTY2llbmNlIGJ5IGlzc3VlLCAyMDEwLTIwMjAiKQoKaXNzdWVzLmJ5LnllYXIuYmFyICsgdGhlbWVfY2xhc3NpYygpICsKICAjMjAxMAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDU5NjEsIHhlbmQgPSA1OTYxLCB5ID0gMCwgeWVuZCA9IDE1MCwgbGluZXR5cGUgPSAyLCBjb2xvdXIgPSAiIzVGODQ5NSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA1OTYxLCB5ID0gMTYwLCBsYWJlbCA9ICIyMDEwIiwgY29sb3VyID0gIiM1Rjg0OTUiKSArCiAgIzIwMTEKICBnZ3Bsb3QyOjphbm5vdGF0ZSgic2VnbWVudCIsIHggPSA2MDEzLCB4ZW5kID0gNjAxMywgeSA9IDAsIHllbmQgPSAxNTAsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA2MDEzLCB5ID0gMTYwLCBsYWJlbCA9ICIyMDExIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxMgogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYwNjQsIHhlbmQgPSA2MDY0LCB5ID0gMCwgeWVuZCA9IDE1MCwgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYwNjQsIHkgPSAxNjAsIGxhYmVsID0gIjIwMTIiLCBjb2xvciA9ICIjOTlBNzk5IikgKwogICMyMDEzCiAgZ2dwbG90Mjo6YW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gNjExNSwgeGVuZCA9IDYxMTUsIHkgPSAwLCB5ZW5kID0gMTUwLCBsaW5ldHlwZSA9IDIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgZ2dwbG90Mjo6YW5ub3RhdGUoInRleHQiLCB4ID0gNjExNSwgeSA9IDE2MCwgbGFiZWwgPSAiMjAxMyIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgIzIwMTQKICBnZ3Bsb3QyOjphbm5vdGF0ZSgic2VnbWVudCIsIHggPSA2MTY2LCB4ZW5kID0gNjE2NiwgeSA9IDAsIHllbmQgPSAxNTAsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA2MTY2LCB5ID0gMTYwLCBsYWJlbCA9ICIyMDE0IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYyMTcsIHhlbmQgPSA2MjE3LCB5ID0gMCwgeWVuZCA9IDE1MCwgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYyMTcsIHkgPSAxNjAsIGxhYmVsID0gIjIwMTUiLCBjb2xvciA9ICIjOTlBNzk5IikgKwogICMyMDE2CiAgZ2dwbG90Mjo6YW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gNjI2OCwgeGVuZCA9IDYyNjgsIHkgPSAwLCB5ZW5kID0gMTUwLCBsaW5ldHlwZSA9IDIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgZ2dwbG90Mjo6YW5ub3RhdGUoInRleHQiLCB4ID0gNjI2OCwgeSA9IDE2MCwgbGFiZWwgPSAiMjAxNiIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgIzIwMTcKICBnZ3Bsb3QyOjphbm5vdGF0ZSgic2VnbWVudCIsIHggPSA2MzIwLCB4ZW5kID0gNjMyMCwgeSA9IDAsIHllbmQgPSAxNTAsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA2MzIwLCB5ID0gMTYwLCBsYWJlbCA9ICIyMDE3IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxOAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYzNzEsIHhlbmQgPSA2MzcxLCB5ID0gMCwgeWVuZCA9IDE1MCwgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYzNzEsIHkgPSAxNjAsIGxhYmVsID0gIjIwMTgiLCBjb2xvciA9ICIjOTlBNzk5IikgKwogICMyMDE5CiAgZ2dwbG90Mjo6YW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gNjQyMiwgeGVuZCA9IDY0MjIsIHkgPSAwLCB5ZW5kID0gMTUwLCBsaW5ldHlwZSA9IDIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgZ2dwbG90Mjo6YW5ub3RhdGUoInRleHQiLCB4ID0gNjQyMiwgeSA9IDE2MCwgbGFiZWwgPSAiMjAxOSIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgIzIwMjAKICBnZ3Bsb3QyOjphbm5vdGF0ZSgic2VnbWVudCIsIHggPSA2NDczLCB4ZW5kID0gNjQ3MywgeSA9IDAsIHllbmQgPSAxNTAsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA2NDczLCB5ID0gMTYwLCBsYWJlbCA9ICIyMDIwIiwgY29sb3IgPSAiIzk5QTc5OSIpCiAgCgpgYGAKClRoZSBuZXh0IGZpZ3VyZSBpcyBhIHBpZSBjaGFydCBvZiBhbGwgaXRlbXMgcHVibGlzaGVkLCBzZXBhcmF0ZWQgYnkgaGF2aW5nIGFic3RyYWN0cyBvciBub3QgaGF2aW5nIGFic3RyYWN0cy4KYGBge3J9CiNjaGVja2luZyBob3cgbWFueSBhcnRpY2xlcyBhcmUgbWlzc2luZyBhYnN0cmFjdHMKICAjdG90YWwgYXJ0aWNsZXMgbWlzc2luZyBhYnN0cmFjdHMgPSAxMzIxMApkYXRhLm5vLmFic3RyYWN0IDwtIGRhdGEgJT4lCiAgZmlsdGVyKGlzLm5hKGFic3RyYWN0KSkgJT4lICNmaWx0ZXJpbmcgdGhvc2Ugcm93cyBpbiBhYnN0cmFjdCB0aGF0IGhhdmUgTkEKICBtdXRhdGUoaGFzLmFic3RyYWN0ID0gIk5vIikKCmRhdGEueWVzLmFic3RyYWN0IDwtIGRhdGEgJT4lCiAgZmlsdGVyKCEoaWQgJWluJSBkYXRhLm5vLmFic3RyYWN0JGlkKSkgJT4lICNmaWx0ZXJpbmcgb3V0IHRob3NlIGFydGljbGVzIGFscmVhZHkgY2F0ZWdvcml6ZWQgYXMgTkEKICBtdXRhdGUoaGFzLmFic3RyYWN0ID0gIlllcyIpCgpkYXRhLmFic3RyYWN0LmJvdGggPC0gcmJpbmQoZGF0YS5uby5hYnN0cmFjdCwgZGF0YS55ZXMuYWJzdHJhY3QpCgpkYXRhLmFic3RyYWN0cyA8LSBkYXRhLmFic3RyYWN0LmJvdGggJT4lCiAgZ3JvdXBfYnkoaGFzLmFic3RyYWN0KSAlPiUKICBjb3VudChoYXMuYWJzdHJhY3QpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUocGVyID0gKDEwMCpuKS9zdW0obikpCgpkYXRhLmFic3RyYWN0cyRwZXIgPC0gcm91bmQoZGF0YS5hYnN0cmFjdHMkcGVyKQoKZ2dwbG90KGRhdGEuYWJzdHJhY3RzLCBhZXMoeD0iIiwgeSA9IG4sIGZpbGwgPSBoYXMuYWJzdHJhY3QpKSArCiAgZ2VvbV9jb2woKSArCiAgdGhlbWVfdm9pZCgpICsKICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpICsKICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAicGFsNSIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKHBlciwiJSIpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdD0wLjUpKSArCiAgZ2d0aXRsZSgiRmlnIDQuIFBlcmNlbnRhZ2Ugb2YgZG9jdW1lbnRzIHdpdGggYW5kIHdpdGhvdXQgYWJzdHJhY3QgaW5mb3JtYXRpb24gZnJvbSBTY2llbmNlIDIwMTAtMjAyMCIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJIYXMgQWJzdHJhY3QiKSkKYGBgCgpUaGlzIGlzIGEgZGlzdHJpYnV0aW9uIG9mIGl0ZW1zIHB1Ymxpc2hlZCBpbiBTY2llbmNlIGJ5IHR5cGUsIHN0YWNrZWQgYnkgd2hldGhlciB0aGV5IGhhdmUgYWJzdHJhY3RzIG9yIG5vdC4KYGBge3J9CiNzdGFja2VkIGJhciBjaGFydCBhYm91dCB3aGV0aGVyIGRpZmZlcmVudCBraW5kcyBvZiBkb2N1bWVudHMgaGF2ZSBhYnN0cmFjdHMgb3Igbm90CgphbGwuYWJzdHJhY3QudHlwZXMgPC0gZ2dwbG90KGRhdGEuYWJzdHJhY3QuYm90aCwgYWVzKHggPSBkb2N1bWVudC50eXBlLCBmaWxsID0gaGFzLmFic3RyYWN0KSkgKwogIGdlb21fYmFyKCkgKwogIHhsYWIoIktpbmRzIG9mIGRvY3VtZW50cyIpICsgCiAgeWxhYigiQW1vdW50IHdpdGggb3Igd2l0aG91dCBhYnN0cmFjdCBpbmZvcm1hdGlvbiIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAicGFsNSIpICsKICBnZ3RpdGxlKCIgICAgICAgRmlnIDUuIERpc3RyaWJ1dGlvbiBvZiBTY2llbmNlIGRvY3VtZW50IHR5cGVzIGFuZCB3ZXRoZXIgdGhleSBoYXZlIGFic3RyYWN0cyIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJIYXMgQWJzdHJhY3QiKSkKCiN0aWx0aW5nIHRoZSB0ZXh0IHNvIGl0IGlzIHJlYWRhYmxlIGFuZCBtb3ZpbmcgZG93bndhcmRzCmFsbC5hYnN0cmFjdC50eXBlcyArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKVG8gZmluZCBhcnRpY2xlcyB0aGF0IEkgZGVlbWVkIHRvIGJlIHJlbGF0ZWQgdG8g4oCcYXJ0aWZpY2lhbCBuZXVyYWwgbmV0d29ya3PigJ0gSSByZXNlYXJjaGVkIHRoZSBmb2xsb3dpbmcga2V5d29yZHMgKG1ha2luZyBzdXJlIHRvIGRpc3JlZ2FyZCBsb3dlciBhbmQgdXBwZXIgY2FzZSBkaWZmZXJlbmNlcyk6IE5ldXJhbCBuZXR3b3JrLCBuZXVyYWwgbmV0d29ya3MsIGFydGlmaWNpYWwgbmV1cmFsIG5ldHdvcmssIGFuZCBhcnRpZmljaWFsIG5ldXJhbCBuZXR3b3Jrcy4gVGhlc2Ugd2VyZSBjaG9zZW4gYmVjYXVzZSDigJxuZXVyYWwgbmV0d29ya3PigJ0gaXMgdGhlIE1lU0ggZGVzY3JpcHRvciAobWVkaWNhbCBzdWJqZWN0IGhlYWRpbmdzIGZyb20gdGhlIG5hdGlvbmFsIGxpYnJhcnkgb2YgbWVkaWNpbmUpIGFuZCB0aGV5IGFyZSB1c3VhbGx5IGEgc3RhbmRhcmQgZm9yIHNldHRpbmcgZGF0YWJhc2Uga2V5d29yZHMuICJBcnRpZmljaWFsIG5ldXJhbCBuZXR3b3JrcyIgaXMgdGhlIGNhdGVnb3J5IHRoYXQgc2VlbWVkIHRvIHBvcCB1cCB0aGUgbW9zdCBpbiB0aGUgam91cm5hbCBTY2llbmNlIGl0c2VsZiwgdGhlIHRlcm0gdGhhdCBhcyBhIGpvdXJuYWwgdGhleSBzZWVtIHRvIGhhdmUgYWdyZWVkIG9uLCBzbyBJIHVzZWQgdGhhdCBhcyB3ZWxsLiBJIHNlYXJjaGVkIHRob3NlIGtleXdvcmRzIG92ZXIgdGhlIGZvbGxvd2luZyBjYXRlZ29yaWVzOiB0aXRsZSwgYWJzdHJhY3QsIGF1dGhvciBrZXl3b3JkcyBhbmQgaW5kZXgga2V5d29yZHMgYW5kIGV4dHJhY3RlZCB0aGUgYXJ0aWNsZXMgdGhhdCBkaWQgY29udGFpbiB0aGF0IGluZm9ybWF0aW9uLiBJIGNvbGxlY3RlZCA3MiBhcnRpY2xlcyBpbiB0b3RhbC4KQWxzbywgSSBzZXBhcmF0ZWQgb3V0IGNvbHVtbnMgc28gdGhhdCBlYWNoIGNvbHVtbiBoYWQgYSBkaXN0aW5jdCBwaWVjZSBvZiBpbmZvcm1hdGlvbiBvdmVyIHRoZSBmb2xsb3dpbmcgY2F0ZWdvcmllczogYXV0aG9yIGlkLCBhdXRob3IsIGFmZmlsaWF0aW9ucywgaW5kZXgga2V5d29yZHMsIHJlZmVyZW5jZXMsIGFuZCBhdXRob3Iga2V5d29yZHMuIFRoYXQgd2F5IGxhdGVyIG9uIEkgY2FuIHdvcmsgd2l0aCB0aG9zZSBwaWVjZXMgc2VwYXJhdGVseS4KCmBgYHtyfQojIGlkZW50aWZ5aW5nIHRpbGVzLCBhYnN0cmFjdHMsIGF1dGhvciBrZXl3b3JkcyBhbmQgaW5kZXgga2V5d29yZHMgd2l0aCBteSBvd24ga2V5d29yZHMKICAjIyBrZXl3b3JkczogUmVwbGljYXRpb24gY3Jpc2lzLCByZXBsaWNhdGlvbiBjcmlzaXMsIFJlcGxpY2FiaWxpdHkgY3Jpc2lzLCByZXBsaWNhYmlsaXR5IGNyaXNpcywgUmVwcm9kdWNpYmlsaXR5IGNyaXNpcywgcmVwcm9kdWNpYmlsaXR5IGNyaXNpcwoKZGF0YS50aXRsZSA8LSBkYXRhICU+JQogIGZpbHRlcihncmVwbCgiTmV1cmFsIG5ldHdvcmt8TmV1cmFsIG5ldHdvcmtzfGFydGlmaWNpYWwgbmV1cmFsIG5ldHdvcmt8YXJ0aWZpY2lhbCBuZXVyYWwgbmV0d29ya3MiLCB0aXRsZSwgaWdub3JlLmNhc2UgPSBUUlVFKSkKCmRhdGEuYWJzdHJhY3QgPC0gZGF0YSAlPiUKICBmaWx0ZXIoZ3JlcGwoIk5ldXJhbCBuZXR3b3JrfE5ldXJhbCBuZXR3b3Jrc3xhcnRpZmljaWFsIG5ldXJhbCBuZXR3b3JrfGFydGlmaWNpYWwgbmV1cmFsIG5ldHdvcmtzIiwgYWJzdHJhY3QsIGlnbm9yZS5jYXNlID0gVFJVRSkpCgpkYXRhLmF1dGhvci5rZXl3b3JkcyA8LSBkYXRhICU+JQogIGZpbHRlcihncmVwbCgiTmV1cmFsIG5ldHdvcmt8TmV1cmFsIG5ldHdvcmtzfGFydGlmaWNpYWwgbmV1cmFsIG5ldHdvcmt8YXJ0aWZpY2lhbCBuZXVyYWwgbmV0d29ya3MiLCBhdXRob3Iua2V5d29yZHMsIGlnbm9yZS5jYXNlID0gVFJVRSkpCgpkYXRhLmluZGV4LmtleXdvcmRzIDwtIGRhdGEgJT4lCiAgZmlsdGVyKGdyZXBsKCJOZXVyYWwgbmV0d29ya3xOZXVyYWwgbmV0d29ya3N8YXJ0aWZpY2lhbCBuZXVyYWwgbmV0d29ya3xhcnRpZmljaWFsIG5ldXJhbCBuZXR3b3JrcyIsIGluZGV4LmtleXdvcmRzLCBpZ25vcmUuY2FzZSA9IFRSVUUpKQoKI0JJTkRJTkcgV0lUSCBUSEUgRVhUUkEgQ09MVU1OUwojcHV0dGluZyBhbGwgb2YgdGhlIGNhdGVnb3JpZXMgYmFjayB0b2dldGhlciAKZGF0YS5uZXR3b3JrcyA8LSBkby5jYWxsKCJyYmluZCIsIGxpc3QoZGF0YS50aXRsZSwgZGF0YS5hYnN0cmFjdCwgZGF0YS5hdXRob3Iua2V5d29yZHMsIGRhdGEuaW5kZXgua2V5d29yZHMpKQoKI2RlbGV0aW5nIGFueSBhcnRpY2xlcyB0aGF0IG1pZ2h0IGhhdmUgcmVwbGljYXRlZApkYXRhLm5ldHdvcmtzIDwtIGRhdGEubmV0d29ya3MgJT4lCiAgZGlzdGluY3QoaWQsIC5rZWVwX2FsbCA9IFRSVUUpCgojc3BsaXR0aW5nIGF1dGhvci5pZCwgCiAgIyNpbiB0byBzZXBhcmF0ZSBjb2x1bW5zIHVzaW5nIHRoZSBzcGxpdHN0YWNrc2hhcGUgbGlicmFyeSwgd2hpY2ggZG9lc24ndCByZXF1aXJlIHlvdSB0byBrbm93IHRoZSB0b3RhbCBhIGNvbHVtbiBuZWVkcyB0byBiZSBzcGxpdCBpbgoKZGF0YS5uZXR3b3JrcyA8LSBjU3BsaXQoZGF0YS5uZXR3b3JrcywgImF1dGhvci5pZCIsIHNlcD0iOyIpCgpkYXRhLm5ldHdvcmtzIDwtICBjU3BsaXQoZGF0YS5uZXR3b3JrcywgImF1dGhvcnMiLCBzZXA9IiwiKQogIApkYXRhLm5ldHdvcmtzIDwtICBjU3BsaXQoZGF0YS5uZXR3b3JrcywgImFmZmlsaWF0aW9ucyIsIHNlcD0iOyIpCgpkYXRhLm5ldHdvcmtzIDwtIGNTcGxpdChkYXRhLm5ldHdvcmtzLCAiaW5kZXgua2V5d29yZHMiLCBzZXA9IjsiKQogIApkYXRhLm5ldHdvcmtzIDwtIGNTcGxpdChkYXRhLm5ldHdvcmtzLCAicmVmZXJlbmNlcyIsIHNlcD0iOyIpCgpkYXRhLm5ldHdvcmtzIDwtIGNTcGxpdChkYXRhLm5ldHdvcmtzLCAiYXV0aG9yLmtleXdvcmRzIiwgc2VwPSI7IikKYGBgCgoKVGhlIGZpc3QgZmlndXJlIHNob3dzIHdoYXQgeWVhciBpdGVtcyByZWxhdGluZyB0byBuZXVyYWwgbmV0d29ya3MgYXJlIHB1Ymxpc2hlZCBpbiBTY2llbmNlIGZyb20gMjAxMC0yMDIwLgpgYGB7cn0KI251bWJlciBvZiBpdGVtcyBieSB5ZWFyIApudW1iZXIudm9sdW1lcy5uZXR3b3JrcyAgPC0gZGF0YS5uZXR3b3JrcyAlPiUKICBjb3VudCh5ZWFyKQoKI3JlbmFtaW5nCm5hbWVzKG51bWJlci52b2x1bWVzLm5ldHdvcmtzKSA8LSBjKCJ5ZWFyIiwgIm4uaXRlbXMuYnkueWVhciIpCgojY2FsY3VsYXRpbmcgdGhlIG51bWJlciBvZiBpdGVtcyBieSBpc3N1ZQpudW1iZXIuaXNzdWVzLm5ldHdvcmtzIDwtIGRhdGEubmV0d29ya3MgJT4lIAogIGdyb3VwX2J5KHllYXIpICU+JQogIGNvdW50KGlzc3VlKQojcmVuYW1pbmcKbmFtZXMobnVtYmVyLmlzc3Vlcy5uZXR3b3JrcykgPC0gYygieWVhciIsICJpc3N1ZSIsICJuLml0ZW1zLmJ5Lmlzc3VlIikKCiNsb29raW5nIGF0IHRoZSBBUlRJQ0xFIGluZm9ybWF0aW9uIGJ5IHllYXIKaXNzdWVzLmJ5LnllYXIuYmFyLm5ldHdvcmtzIDwtIGdncGxvdChudW1iZXIudm9sdW1lcy5uZXR3b3JrcykgKwogIGdlb21fbGluZShhZXMoeD0geWVhciwgeSA9IG4uaXRlbXMuYnkueWVhciksIGNvbG9yID0gIiM1Rjg0OTUiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMjAxMCwgMjAxMSwgMjAxMiwgMjAxMywgMjAxNCwgMjAxNSwgMjAxNiwgMjAxNywgMjAxOCwgMjAxOSwgMjAyMCkpICsKICMgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTApKSArCiAgeGxhYigiWWVhciIpICsgCiAgeWxhYigiTnVtYmVyIG9mIGl0ZW1zIikgKwogICNsYWJzKHRpdGxlID0gIiIpICsKICB0aGVtZV9jbGFzc2ljKCkKCmlzc3Vlcy5ieS55ZWFyLmJhci5uZXR3b3JrcwpgYGAKClRoZSBuZXh0IGZpZ3VyZSB2aXN1YWxpemVzIHRoZSBudW1iZXIgb2YgaXRlbXMgcHVibGlzaGVkIGluIFNjaWVuY2UgcmVsYXRpbmcgdG8gbmV1cmFsIG5ldHdvcmtzIGJ5IGlzc3VlLCBhbHNvIGluZGljYXRlZCBieSB5ZWFyLgpgYGB7cn0KI2NvdW50aW5nIG51bWJlciBvZiBhcnRpY2xlcyByZWxhdGVkIHRvIG5ldXJhbCBuZXR3b3JrcyBieSBpc3N1ZSAoNTQpCmlzc3Vlcy5vZi5uZXR3b3JrcyA8LSBkYXRhLm5ldHdvcmtzICU+JQogIGdyb3VwX2J5KGlzc3VlKSAlPiUKICBjb3VudChpc3N1ZSwgLmRyb3AgPSBGQUxTRSkKCiNnZXR0aW5nIGEgbGlzdCBvZiBhbGwgaXNzdWVzICg1NjkpCmFsbC5pc3N1ZXMgPC0gbnVtYmVyLmlzc3VlcyAlPiUKICB1bmdyb3VwKCkgJT4lCiAgc2VsZWN0KC15ZWFyLCAtbi5pdGVtcy5ieS5pc3N1ZSkgJT4lCiAgbXV0YXRlKG4gPSAwKQoKI2ZpbHRlcmluZyBvdXQgdGhlIGlzc3VlcyB0aGF0IGhhdmUgbmV1cmFsIG5ldHdvcmsgaW5mb3JtYXRpb24gaW4gdGhlbSAgKDUxNS81MTIpCm51bWJlci5pc3N1ZXMubmV0d29ya3MgPC0gYWxsLmlzc3VlcyAlPiUKICBmaWx0ZXIoIShpc3N1ZSAlaW4lIGlzc3Vlcy5vZi5uZXR3b3JrcyRpc3N1ZSkpCgojYWRkaW5nIHRoZSBkYXRhYmFzZXMgYWJvdmUgdG9nZXRoZXIgKGNvdW50ZWQgYXJ0aWNsZXMgcmVsYXRlZCB0byBuZXVyYWwgbmV0d29ya3MgYW5kIHRoZSBvbmVzIHRoYXQgZG9uJ3QsIHdpdGggMCBudW1iZXJzKQp5ZWFyLmNvdW50IDwtIHJiaW5kKG51bWJlci5pc3N1ZXMubmV0d29ya3MsIGlzc3Vlcy5vZi5uZXR3b3JrcykKCmlzc3Vlcy5ieS55ZWFyLmJhciA8LSBnZ3Bsb3QoeWVhci5jb3VudCkgKwogIGdlb21fbGluZShhZXMoeD0gaXNzdWUsIHkgPSBuKSwgY29sb3IgPSAiIzQwNjM0MyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAxLCAyLCAzLCA0LCA1LCA2KSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDU5MDAsIDYwMDAsIDYxMDAsIDYyMDAsIDYzMDAsIDY0MDAsIDY1MDAsIDY2MDAsIDY3MDAsIDY4MDAsIDY5MDApKSArCiAgeGxhYigiSXNzdWUgbnVtYmVyIikgKyAKICB5bGFiKCJOdW1iZXIgb2YgaXRlbXMiKSArCiAgZ2d0aXRsZSgiRmlnIDYuIE51bWJlciBvZiBwdWJsaXNoZWQgaXRlbXMgcmVsYXRlZCB0byBuZXVyYWwgbmV0d29ya3MgYnkgaXNzdWUgaW4gU2NpZW5jZSwgMjAxMC0yMDIwIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkgKwogICMyMDEwOQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDU5NjEsIHhlbmQgPSA1OTYxLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDU5NjEsIHkgPSA2LCBsYWJlbCA9ICIyMDEwIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxMQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYwMTMsIHhlbmQgPSA2MDEzLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYwMTMsIHkgPSA2LCBsYWJlbCA9ICIyMDExIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxMgogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYwNjQsIHhlbmQgPSA2MDY0LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYwNjQsIHkgPSA2LCBsYWJlbCA9ICIyMDEyIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxMwogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYxMTUsIHhlbmQgPSA2MTE1LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYxMTUsIHkgPSA2LCBsYWJlbCA9ICIyMDEzIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYxNjYsIHhlbmQgPSA2MTY2LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYxNjYsIHkgPSA2LCBsYWJlbCA9ICIyMDE0IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYyMTcsIHhlbmQgPSA2MjE3LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYyMTcsIHkgPSA2LCBsYWJlbCA9ICIyMDE1IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNgogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYyNjgsIHhlbmQgPSA2MjY4LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYyNjgsIHkgPSA2LCBsYWJlbCA9ICIyMDE2IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNwogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYzMjAsIHhlbmQgPSA2MzIwLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYzMjAsIHkgPSA2LCBsYWJlbCA9ICIyMDE3IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxOAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYzNzEsIHhlbmQgPSA2MzcxLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYzNzEsIHkgPSA2LCBsYWJlbCA9ICIyMDE4IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxOQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDY0MjIsIHhlbmQgPSA2NDIyLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDY0MjIsIHkgPSA2LCBsYWJlbCA9ICIyMDE5IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAyMAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDY0NzMsIHhlbmQgPSA2NDczLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDY0NzMsIHkgPSA2LCBsYWJlbCA9ICIyMDIwIiwgY29sb3IgPSAiIzk5QTc5OSIpCiAgCmlzc3Vlcy5ieS55ZWFyLmJhciArIHRoZW1lX2NsYXNzaWMoKQpgYGAKCk5leHQgaXMgYSBoaXN0b2dyYW0gb2YgbnVtYmVyIG9mIGNpdGF0aW9ucyByZWNpZXZlZCBieSBuZXVyYWwgbmV0d29yayBpdGVtcyBmcm9tIFNjaWVuY2UgMjAxMC0yMDIwLgpgYGB7cn0KI2Rlc2NyaXB0aXZlIHZpc3VhbGl6YXRpb24KICAjIyBvbmU6IGhpc3RvZ3JhbSBvZiB0aGUgY2l0YXRpb24sIGJpbnMgd2l0aCAzMCBjb3VudHMKY2l0YXRpb24uaGlzdCA8LSBnZ3Bsb3QoZGF0YS5uZXR3b3JrcywgYWVzKHg9Y2l0ZWQuYnkpKSArCiAgZ2VvbV9oaXN0b2dyYW0oZmlsbCA9ICIjNDA2MzQzIiwgYmlud2lkdGg9IDMwLCBjZW50ZXIgPSAwLjEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAxMDAsIDIwMCwgMzAwLCA0MDAsIDUwMCwgNjAwLCA3MDAsIDgwMCwgOTAwLCAxMDAwLCAxMTAwLCAxMjAwLCAxMzAwLCAxNDAwLCAxNTAwLCAxNjAwLCAxNzAwLCAxODAwLCAxOTAwKSkgKwogIHhsYWIoIkNpdGF0aW9uIGNvdW50cyIpICsgCiAgeWxhYigiTnVtYmVyIG9mIGFydGljbGVzIikgKwogIGxhYnModGl0bGUgPSAiRmlnIDguIERpc3RyaWJ1dGlvbiBvZiBhbW91bnQgb2YgY2l0YXRpb25zIHJlY2VpdmVkIGJ5IG5ldXJhbCBuZXR3b3JrIGl0ZW1zIikKCmNpdGF0aW9uLmhpc3QgKyB0aGVtZV9jbGFzc2ljKCkKYGBgCgpUbyB2aWV3IHRoZSBoaXN0b2dyYW0gZGlzdHJpYnV0aW9uIG1vcmUgY2xlYXJseSwgSSBhbHNvIHJhbiBhIHZlcnNpb24gdGhhdCBleGNsdWRlZCB0aGUgb3V0bGllcnMgKHdoaWNoIEkgY2F0ZWdvcml6ZXMgYXMgb3ZlciA1MDAgY2l0YXRpb25zKQpgYGB7cn0KI3R3bzogdmlzdWFsaXphdGlvbiBvZiB0aGUgY2l0YXRpb24gY291bnRzIGV4Y2x1ZGluZyBvdXRsaWVycyAoPDUwMCkKICAjIyBiaW53aWR0aCAxMApkYXRhLm5ldHdvcmtzLmNpdGF0aW9uLm1vc3QgPC0gZGF0YS5uZXR3b3JrcyAlPiUKICBmaWx0ZXIoY2l0ZWQuYnkgPCA1MDApCgpjaXRhdGlvbi5oaXN0Lm1vc3QgPC0gZ2dwbG90KGRhdGEubmV0d29ya3MuY2l0YXRpb24ubW9zdCwgYWVzKHg9Y2l0ZWQuYnkpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAzMCwgZmlsbCA9ICIjNDA2MzQzIikgKwogICAjIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDEwLCA1MCwgMTAwLCAxNTAsIDIwMCwgMjUwLCAzMDAsIDM1MCwgNDAwLCAKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NTAsIDUwMCwgNTUwLCA2MDAsIDY1MCwgNzAwLCA3NTAsIDgwMCkpICsKICB4bGFiKCJDaXRhdGlvbiBjb3VudHMsIHdpdGhvdXQgb3V0bGllcnMiKSArIAogIHlsYWIoIk51bWJlciBvZiBhcnRpY2xlcyIpICsKICBsYWJzKHRpdGxlID0gIkZpZyA5LiBEaXN0cmlidXRpb24gb2YgYW1tb3VudCBvZiBjaXRhdGlvbnMgcmVjaWV2ZWQgYnkgbmV1cmFsIG5ldHdvcmsgaXRlbXMsIGV4Y2x1ZGluZyBvdXRsaWVycyAoNTAwKSIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkpCgpjaXRhdGlvbi5oaXN0Lm1vc3QgKyB0aGVtZV9jbGFzc2ljKCkKYGBgCgpUaGUgZm9sbG93aW5nIHBpZSBjaGFydCBjYXRlZ29yaXplcyB3aGF0IGl0ZW1zIGhhdmUgb3IgZG8gbm90IGhhdmUgYWJzdHJhY3QgaW5mb3JtYXRpb24uCmBgYHtyfQojcGllIGNoYXJ0IG9mIHRoZSBwZXJjZW50YWdlIG9mIGFydGljbGVzIHdpdGggbm8gYXJ0aWNsZXMKCiNjaGVja2luZyBob3cgbWFueSBhcnRpY2xlcyBhcmUgbWlzc2luZyBhYnN0cmFjdHMKICAjdG90YWwgYXJ0aWNsZXMgbWlzc2luZyBhYnN0cmFjdHMgPSAxMzIxMApkYXRhLm5uLm5vLmFic3RyYWN0IDwtIGRhdGEubmV0d29ya3MgJT4lCiAgZmlsdGVyKGlzLm5hKGFic3RyYWN0KSkgJT4lICNmaWx0ZXJpbmcgdGhvc2Ugcm93cyBpbiBhYnN0cmFjdCB0aGF0IGhhdmUgTkEKICBtdXRhdGUoaGFzLmFic3RyYWN0ID0gIk5vIikKCmRhdGEubm4ueWVzLmFic3RyYWN0IDwtIGRhdGEubmV0d29ya3MgJT4lCiAgZmlsdGVyKCEoaWQgJWluJSBkYXRhLm5uLm5vLmFic3RyYWN0JGlkKSkgJT4lICNmaWx0ZXJpbmcgb3V0IHRob3NlIGFydGljbGVzIGFscmVhZHkgY2F0ZWdvcml6ZWQgYXMgTkEKICBtdXRhdGUoaGFzLmFic3RyYWN0ID0gIlllcyIpCgpkYXRhLm5uLmFic3RyYWN0LmJvdGggPC0gcmJpbmQoZGF0YS5ubi5uby5hYnN0cmFjdCwgZGF0YS5ubi55ZXMuYWJzdHJhY3QpCgpkYXRhLm5uLmFic3RyYWN0cyA8LSBkYXRhLm5uLmFic3RyYWN0LmJvdGggJT4lCiAgZ3JvdXBfYnkoaGFzLmFic3RyYWN0KSAlPiUKICBjb3VudChoYXMuYWJzdHJhY3QpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUocGVyID0gKDEwMCpuKS9zdW0obikpCgpkYXRhLm5uLmFic3RyYWN0cyRwZXIgPC0gcm91bmQoZGF0YS5ubi5hYnN0cmFjdHMkcGVyKQoKZ2dwbG90KGRhdGEubm4uYWJzdHJhY3RzLCBhZXMoeD0iIiwgeSA9IGhhcy5hYnN0cmFjdCwgZmlsbCA9IGhhcy5hYnN0cmFjdCwgcGFsZXR0ZSA9ICJCdUduIikpICsKICAgZ2VvbV9jb2woKSArCiAgdGhlbWVfdm9pZCgpICsKICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpICsKICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAicGFsNSIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKHBlciwiJSIpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdD0wLjUpKSArCiAgZ2d0aXRsZSgiRmlnIDEwLiBQZXJjZW50YWdlcyBvZiBpdGVtcyBhYm91dCBuZXVyYWwgbmV0d29ya3MgCiAgICAgICAgICB3aXRoIG9yIHdpdGhvdXQgYWJzdHJhY3RzIGluIFNjaWVuY2UgMjAxMC0yMDIwIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIkhhcyBBYnN0cmFjdCIpKQpgYGAKClRoZSBuZXh0IGZpZ3VyZSBpcyBhIGRpc3RyaWJ1dGlvbiBvZiBkb2N1bWVudCB0eXBlcyBhYm91dCBuZXVyYWwgbmV0d29ya3MgYW5kIHdoZXRoZXIgdGhleSBoYXZlIGFic3RyYWN0cyBpbiBTY2llbmNlIDIwMTAtMjAyMC4KYGBge3J9CiNjaGVja2luZyBieSBkb2N1bWVudCB0eXBlIHdoYXQgdGhpbmdzIGFyZSBtaXNzaW5nIGFic3RyYWN0cwpubi5hYnN0cmFjdC50eXBlcyA8LSBnZ3Bsb3QoZGF0YS5ubi5hYnN0cmFjdC5ib3RoLCBhZXMoeCA9IGRvY3VtZW50LnR5cGUsIGZpbGwgPSBoYXMuYWJzdHJhY3QsIHBhbGV0dGUgPSAiQnVHbiIpKSArCiAgZ2VvbV9iYXIoKSArCiAgeGxhYigiS2luZHMgb2YgZG9jdW1lbnRzIikgKyAKICB5bGFiKCJBbW91bnQgd2l0aCBvciB3aXRob3V0IGFic3RyYWN0IGluZm9ybWF0aW9uIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCdUduIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIkhhcyBBYnN0cmFjdCIpKSArCiAgZ2d0aXRsZSgiRmlnIDExLiBEaXN0cmlidXRpb24gb2YgZG9jdW1lbnQgdHlwZXMgYWJvdXQgbmV1cmFsIG5ldHdvcmtzIGFuZCB3ZXRoZXIgCiAgICAgICAgICB0aGV5IGhhdmUgYWJzdHJhY3RzIGluIFNjaWVuY2UgMjAxMC0yMDIwIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKCiN0aWx0aW5nIHRoZSB0ZXh0IHNvIGl0IGlzIHJlYWRhYmxlIGFuZCBtb3ZpbmcgZG93bndhcmRzCm5uLmFic3RyYWN0LnR5cGVzICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgpUaGUgbmV4dCBmaWd1cmUgaXMgYSB3b3JkIGNsb3VkIG9mIHRoZSBtb3N0IGNvbW1vbiB3b3JkcyBpbiB0aGUgYWJzdHJhY3QsIGluY2x1ZGluZyBjb21tb24gd29yZHMuIApgYGB7cn0KI21ha2luZyBhIGxvbmcgbGlzdCBvZiBhbGwgdGhlIGtleXdvcmRzIHVzZWQgaW4gYXJ0aWNsZXMgYWJvdXQgbmV1cmFsIG5ldHdvcmtzCmluZGV4LmtleXdvcmRzIDwtIGRhdGEubmV0d29ya3MgJT4lCiAgc2VsZWN0KGluZGV4LmtleXdvcmRzXzAxOmluZGV4LmtleXdvcmRzXzY2LCBpZCkKCmluZGV4LmtleXdvcmRzID0gbWVsdChpbmRleC5rZXl3b3JkcyxpZC52YXJzPWMoImlkIikpCgojbWFraW5nIGV2ZXJ5dGhpbmcgbG93ZXJjYXNlCmluZGV4LmtleXdvcmRzJHZhbHVlID0gdG9sb3dlcihpbmRleC5rZXl3b3JkcyR2YWx1ZSkKCmluZGV4LmtleXdvcmRzIDwtIGluZGV4LmtleXdvcmRzICU+JQogIHNlbGVjdCgtaWQsIC12YXJpYWJsZSkgJT4lCiAgZHJvcF9uYSh2YWx1ZSkgJT4lCiAgY291bnQodmFsdWUpCgp3b3JkY2xvdWQod29yZHMgPSBpbmRleC5rZXl3b3JkcyR2YWx1ZSwgZnJlcSA9IGluZGV4LmtleXdvcmRzJG4sIG1pbi5mcmVxID0gNSwKICAgICAgICAgIG1heC53b3Jkcz0yMDAsIHJhbmRvbS5vcmRlcj1GQUxTRSwgcm90LnBlcj0wLjM1LAogICAgICAgICAgY29sb3JzPWJyZXdlci5wYWwoOCwgIkRhcmsyIiksIHNjYWxlPWMoMi4wLDAuMjUpKQpgYGAKClRvIG1vcmUgY2xlYXJseSBzZWUgdGhlIHdvcmRzIG9mIGludGVyZXN0LCBJIGV4Y2x1ZGVkIHNvbWUgb2YgdGhlIHdvcmRzIHRoYXQgYXJlIG1vcmUgY29tbW9uIGluIHRoZSBFbmdsaXNoIGxhbmd1YWdlIGFuZCB0aGVyZWZvcmUgbWlnaHQgYmUgbGVzcyBpbmRpY2F0aXZlIG9mIHdoYXQgdGhlIGFic3RyYWN0cyBhcmUgYWJvdXQuIFRoZSBrZXl3b3JkcyBJIGV4Y2x1ZGVkIHdlcmU6IHRoZSwgb2YsIGFuZCwgaW4sIGEsIHRvLCBmb3IsIHRoYXQsIHdlLCBpcywgYnksIHdpdGgsIHRoaXMsIGFyZSwgb24sIGFuLCBjYW4sIGZyb20sIGFsbCwgwqksIGJlLCB3aGljaCwgaG93LCBvciwgb3VyLCBpdC4KYGBge3J9CiNtYWtpbmcgd29yZGNsb3VkIG9mIHRoZSBhYnN0cmFjdCBpbmZvcm1hdGlvbgphYnN0cmFjdC53b3JkcyA8LSBkYXRhLm5ldHdvcmtzICU+JQogIHNlbGVjdChpZCwgYWJzdHJhY3QpICU+JQogIGRyb3BfbmEoYWJzdHJhY3QpCgojdGFraW5nIGF3YXkgcHVuY3R1YXRpb24KYWJzdHJhY3Qud29yZHMkYWJzdHJhY3QgPC0gZ3N1YignW1s6cHVuY3Q6XSBdKycsJyAnLCBhcy5jaGFyYWN0ZXIoYWJzdHJhY3Qud29yZHMkYWJzdHJhY3QpKQogIAojbWFraW5nIHdob2xlIHRleHQgbG93ZXJjYXNlCmFic3RyYWN0LndvcmRzJGFic3RyYWN0ID0gdG9sb3dlcihhYnN0cmFjdC53b3JkcyRhYnN0cmFjdCkKCiNzZXBhcmF0aW5nIGNvbHVtbiBvdXQgaW4gdG8gaW5kaXZpZHVhbCB3b3JkcwphYnN0cmFjdC53b3JkcyA8LSBjU3BsaXQoYWJzdHJhY3Qud29yZHMsICJhYnN0cmFjdCIsIHNlcD0iICIpCgojdHJpbW1pbmcgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZQp0cmltd3NfZGYgPC0gZnVuY3Rpb24oeCwgLi4uKXsKICB4W10gPC0gbGFwcGx5KHgsIHRyaW13cywgLi4uKQogIHgKfQphYnN0cmFjdC53b3JkcyA8LSB0cmltd3NfZGYoYWJzdHJhY3Qud29yZHMpCgojY29tYmluaW5nIGluIHRvIG9uZSBjb2x1bW4KYWJzdHJhY3Qud29yZHMgPSBtZWx0KGFic3RyYWN0LndvcmRzLCBpZC52YXJzPWMoImlkIikpCgojY291bnRpbmcgdGhlIG51bWJlciBvZiB3b3JkcwphYnN0cmFjdC53b3JkcyA8LSBhYnN0cmFjdC53b3JkcyAlPiUKICBzZWxlY3QoLWlkLCAtdmFyaWFibGUpICU+JQogIGRyb3BfbmEodmFsdWUpICU+JQogIGNvdW50KHZhbHVlKQoKI21ha2luZyBhIHdvcmQgY2xvdWQgaW5jbHVkaW5nIGFsbCB0aGUgd29yZHMKd29yZGNsb3VkKHdvcmRzID0gYWJzdHJhY3Qud29yZHMkdmFsdWUsIGZyZXEgPSBhYnN0cmFjdC53b3JkcyRuLCBtaW4uZnJlcSA9IDMsCiAgICAgICAgICBtYXgud29yZHM9MjAwLCByYW5kb20ub3JkZXI9RkFMU0UsIHJvdC5wZXI9MC4zNSwgc2NhbGU9Yyg1LjAsMC41KSwKICAgICAgICAgIGNvbG9ycz1icmV3ZXIucGFsKDgsICJEYXJrMiIpKQoKI3JlbW92aW5nIGNvbW1vbiB3b3JkcwphYnN0cmFjdC53b3JkcyA8LSBhYnN0cmFjdC53b3Jkc1shZ3JlcGwoInRoZXxvZnxhbmR8aW58YXx0b3xmb3J8dGhhdHx3ZXxpc3xieXx3aXRofHRoaXN8YXJlfG9ufGFufGNhbnxmcm9tfGFsbHzCqXxiZXx3aGljaHxob3d8b3J8b3VyfGl0IiwgYWJzdHJhY3Qud29yZHMkdmFsdWUpLF0KCiNtYWtpbmcgd29yZCBjbG91ZAp3b3JkY2xvdWQod29yZHMgPSBhYnN0cmFjdC53b3JkcyR2YWx1ZSwgZnJlcSA9IGFic3RyYWN0LndvcmRzJG4sIG1pbi5mcmVxID0gMywKICAgICAgICAgbWF4LndvcmRzPTIwMCwgcmFuZG9tLm9yZGVyPUZBTFNFLCByb3QucGVyPTAuMzUsCiAgICAgICAgY29sb3JzPWJyZXdlci5wYWwoOCwgIkRhcmsyIiksIHNjYWxlPWMoMy4wLDAuMjUpKQpgYGAKCkkgc2VsZWN0ZWQgNCBhcnRpY2xlcyByYW5kb21seSB0byBxdWFsaXRhdGl2ZWx5IGNvZGUuIFR3byB3ZXJlIHRvdGFsbHkgcmFuZG9tIGFuZCBJIGdvdDoKCeKBgwkgTmV1cmFsIHNjZW5lIHJlcHJlc2VudGF0aW9uIGFuZCByZW5kZXJpbmcsIDIwMTguIFZvbCAzNjAsIGlzc3VlIDYzOTQuIGRvaTogMTAuMTEyNi9zY2llbmNlLmFhcjYxNzAKCeKBgwlUaGUgYmlvY2hlbWljYWwgYmFzaXMgb2YgbWljcm9STkEgdGFyZ2V0aW5nIGVmZmljYWN5LCAyMDE5LiBWb2wgMzY2LiBkb2k6IDEwLjExMjYvc2NpZW5jZS5hYXYxNzQxCk9uZSB3YXMgZnJvbSB0aGUgdG9wIDI1JSBvZiBjaXRhdGlvbnMgcmVjZWl2ZWQgKG1vcmUgdGhhbiAxNzEuNSBjaXRhdGlvbnMpCgnigYMJVGVycmVzdHJpYWwgZ3Jvc3MgY2FyYm9uIGRpb3hpZGUgdXB0YWtlOiBHbG9iYWwgZGlzdHJpYnV0aW9uIGFuZCBjb3ZhcmlhdGlvbiB3aXRoIGNsaW1hdGUuIGRvaTogMTAuMTEyNi9zY2llbmNlLjExODQ5ODQKT25lIHdhcyByYW5kb21seSBzZWxlY3RlZCBmcm9tIHRoZSB5ZWFyIHdpdGggdGhlIG1vc3QgYXJ0aWNsZXMgYWJvdXQgbmV1cmFsIG5ldHdvcmtzICgyMDE5KQoJ4oGDCU1hY2hpbmUgbGVhcm5pbmcgdHJhbnNmb3JtcyBob3cgbWljcm9zdGF0ZXMgYXJlIHNhbXBsZWQsIDIwMTkuIFZvbCAzNjUuIElzc3VlIDY0NTcuIGRvaTogMTAuMTEyNi9zY2llbmNlLmFheTI1NjgKQXMgYSBub3RlLCB0aGlzIHdpbGwgcmV0dXJuIGRpZmZlcmVudCBhcnRpY2xlcyBldmVyeSB0aW1lIGl0IGlzIHJ1bi4gSSd2ZSBzZWxlY3RlZCB0aGUgYXJ0aWNsZXMgdGhhdCBhcHBlYXJlZCB0aGUgZmlyc3QgdGltZS4KYGBge3J9CiNyYW5kb21seSBzZWxlY3RpbmcgYXJ0aWNsZXMgdG8gY2xvc2UgcmVhZAogICMjbm90ZSwgdGhpcyB3aWxsIHJldHVybiBkaWZmZXJlbnQgYXJ0aWNsZXMgZXZlcnkgdGltZSBpdCBpcyBydW4uIEkndmUgc2VsZWN0ZWQgdGhlIGFydGljbGVzIHRoYXQgYXBwZWFyZWQgdGhlIGZpcnN0IHRpbWUuCgojcmFuZG9tbHkgc2VsZWN0aW5nIDIgYXJ0aWNsZXMgZnJvbSB0aGUgd2hvbGUgbmV0d29ya3MgZGF0YWJhc2UKc2FtcGxlX24oZGF0YS5uZXR3b3JrcywgMikKICAjc2VsZWN0ZWQ6IE5ldXJhbCBzY2VuZSByZXByZXNlbnRhdGlvbiBhbmQgcmVuZGVyaW5nLCAyMDE4LiBWb2wgMzYwLCBpc3N1ZSA2Mzk0LiBkb2k6IDEwLjExMjYvc2NpZW5jZS5hYXI2MTcwCiAgI3NlbGVjdGVkOiBUaGUgYmlvY2hlbWljYWwgYmFzaXMgb2YgbWljcm9STkEgdGFyZ2V0aW5nIGVmZmljYWN5LCAyMDE5LiBWb2wgMzY2LiBkb2k6IDEwLjExMjYvc2NpZW5jZS5hYXYxNzQxCgojcmFuZG9tbHkgc2VsZWN0aW5nIDEgYXJ0aWNsZSB3aXRoaW4gdGhlIHRvcCAyNSUgbnVtYmVyIG9mIGNpdGF0aW9ucwogICMjIGV4dHJhY3RpbmcgdGhlIHF1YW50aWxlcyBvZiB0aGUgZGF0YXNldCwgdXBwZXIgNzUlID0gMTcxLjUKcXVhbnRpbGUoZGF0YS5uZXR3b3JrcyRjaXRlZC5ieSwgbmEucm09VFJVRSkKCmRhdGEubmV0d29ya3MudG9wLjc1cGVyIDwtIGRhdGEubmV0d29ya3MgJT4lCiAgZmlsdGVyKGNpdGVkLmJ5ID4gMTcxLjUpCgpzYW1wbGVfbihkYXRhLm5ldHdvcmtzLnRvcC43NXBlciwxKQogICNzZWxlY3RlZDogVGVycmVzdHJpYWwgZ3Jvc3MgY2FyYm9uIGRpb3hpZGUgdXB0YWtlOiBHbG9iYWwgZGlzdHJpYnV0aW9uIGFuZCBjb3ZhcmlhdGlvbiB3aXRoIGNsaW1hdGUuIGRvaTogMTAuMTEyNi9zY2llbmNlLjExODQ5ODQKCiNyYW5kb21seSBzZWxlY3RpbmcgMSBhcnRpY2xlIGZyb20gMjAxOSAodGhlIHllYXIgd2l0aCB0aGUgbW9zdCBhcnRpY2xlcyBwdWJsaXNoZWQpCmRhdGEubmV0d29ya3MuMjAxOSA8LSBkYXRhLm5ldHdvcmtzICU+JQogIGZpbHRlcih5ZWFyID09ICIyMDE5IikKCnNhbXBsZV9uKGRhdGEubmV0d29ya3MuMjAxOSwgMSkKICAjc2VsZWN0ZWQ6IE1hY2hpbmUgbGVhcm5pbmcgdHJhbnNmb3JtcyBob3cgbWljcm9zdGF0ZXMgYXJlIHNhbXBsZWQsIDIwMTkuIFZvbCAzNjUuIElzc3VlIDY0NTcuIGRvaTogMTAuMTEyNi9zY2llbmNlLmFheTI1NjgKYGBg